TextureStorage11.cpp (176339B)
1 // 2 // Copyright 2012 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 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived 8 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 9 // texture. 10 11 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" 12 13 #include <tuple> 14 15 #include "common/MemoryBuffer.h" 16 #include "common/utilities.h" 17 #include "libANGLE/Context.h" 18 #include "libANGLE/ImageIndex.h" 19 #include "libANGLE/formatutils.h" 20 #include "libANGLE/renderer/d3d/EGLImageD3D.h" 21 #include "libANGLE/renderer/d3d/TextureD3D.h" 22 #include "libANGLE/renderer/d3d/d3d11/Blit11.h" 23 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" 24 #include "libANGLE/renderer/d3d/d3d11/Context11.h" 25 #include "libANGLE/renderer/d3d/d3d11/Image11.h" 26 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" 27 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" 28 #include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h" 29 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" 30 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" 31 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" 32 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" 33 34 namespace rx 35 { 36 TextureStorage11::SamplerKey::SamplerKey() 37 : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false) 38 {} 39 40 TextureStorage11::SamplerKey::SamplerKey(int baseLevel, 41 int mipLevels, 42 bool swizzle, 43 bool dropStencil) 44 : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil) 45 {} 46 47 bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const 48 { 49 return std::tie(baseLevel, mipLevels, swizzle, dropStencil) < 50 std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil); 51 } 52 53 TextureStorage11::ImageKey::ImageKey() 54 : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI) 55 {} 56 57 TextureStorage11::ImageKey::ImageKey(int level, 58 bool layered, 59 int layer, 60 GLenum access, 61 GLenum format) 62 : level(level), layered(layered), layer(layer), access(access), format(format) 63 {} 64 65 bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const 66 { 67 return std::tie(level, layered, layer, access, format) < 68 std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format); 69 } 70 71 MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples, 72 const gl::ImageIndex &indexSS, 73 const gl::ImageIndex &indexMS) 74 : samples(samples), indexSS(indexSS), indexMS(indexMS), msTextureNeedsResolve(false) 75 {} 76 77 MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {} 78 79 TextureStorage11::TextureStorage11(Renderer11 *renderer, 80 UINT bindFlags, 81 UINT miscFlags, 82 GLenum internalFormat, 83 const std::string &label) 84 : TextureStorage(label), 85 mRenderer(renderer), 86 mTopLevel(0), 87 mMipLevels(0), 88 mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())), 89 mTextureWidth(0), 90 mTextureHeight(0), 91 mTextureDepth(0), 92 mDropStencilTexture(), 93 mBindFlags(bindFlags), 94 mMiscFlags(miscFlags) 95 {} 96 97 TextureStorage11::~TextureStorage11() 98 { 99 mSrvCacheForSampler.clear(); 100 } 101 102 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, 103 const Renderer11DeviceCaps &renderer11DeviceCaps, 104 BindFlags flags) 105 { 106 UINT bindFlags = 0; 107 108 const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); 109 if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) 110 { 111 bindFlags |= D3D11_BIND_SHADER_RESOURCE; 112 } 113 if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN && flags.unorderedAccess) 114 { 115 bindFlags |= D3D11_BIND_UNORDERED_ACCESS; 116 } 117 if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) 118 { 119 bindFlags |= D3D11_BIND_DEPTH_STENCIL; 120 } 121 if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && flags.renderTarget) 122 { 123 bindFlags |= D3D11_BIND_RENDER_TARGET; 124 } 125 126 return bindFlags; 127 } 128 129 DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, 130 const Renderer11DeviceCaps &renderer11DeviceCaps, 131 BindFlags bindFlags, 132 int levels) 133 { 134 UINT miscFlags = 0; 135 136 const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); 137 if (bindFlags.renderTarget) 138 { 139 if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel)) 140 { 141 miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; 142 } 143 } 144 145 return miscFlags; 146 } 147 148 UINT TextureStorage11::getBindFlags() const 149 { 150 return mBindFlags; 151 } 152 153 UINT TextureStorage11::getMiscFlags() const 154 { 155 return mMiscFlags; 156 } 157 158 int TextureStorage11::getTopLevel() const 159 { 160 // Applying top level is meant to be encapsulated inside TextureStorage11. 161 UNREACHABLE(); 162 return mTopLevel; 163 } 164 165 bool TextureStorage11::isRenderTarget() const 166 { 167 return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; 168 } 169 170 bool TextureStorage11::isManaged() const 171 { 172 return false; 173 } 174 175 bool TextureStorage11::supportsNativeMipmapFunction() const 176 { 177 return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0; 178 } 179 180 int TextureStorage11::getLevelCount() const 181 { 182 return mMipLevels - mTopLevel; 183 } 184 185 int TextureStorage11::getLevelWidth(int mipLevel) const 186 { 187 return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1); 188 } 189 190 int TextureStorage11::getLevelHeight(int mipLevel) const 191 { 192 return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1); 193 } 194 195 int TextureStorage11::getLevelDepth(int mipLevel) const 196 { 197 return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1); 198 } 199 200 angle::Result TextureStorage11::getMippedResource(const gl::Context *context, 201 const TextureHelper11 **outResource) 202 { 203 return getResource(context, outResource); 204 } 205 206 angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context, 207 const gl::ImageIndex &index, 208 UINT *outSubresourceIndex) const 209 { 210 UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel); 211 UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.getLayerIndex() : 0); 212 UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); 213 ASSERT(subresource != std::numeric_limits<UINT>::max()); 214 *outSubresourceIndex = subresource; 215 return angle::Result::Continue; 216 } 217 218 angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context, 219 const gl::TextureState &textureState, 220 const gl::SamplerState &sampler, 221 const d3d11::SharedSRV **outSRV) 222 { 223 ANGLE_TRY(resolveTexture(context)); 224 // Make sure to add the level offset for our tiny compressed texture workaround 225 const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel(); 226 const bool swizzleRequired = SwizzleRequired(textureState); 227 const bool mipmapping = gl::IsMipmapFiltered(sampler.getMinFilter()); 228 unsigned int mipLevels = 229 mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1; 230 231 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, 232 // which corresponds to GL level 0) 233 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel); 234 235 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) 236 { 237 ASSERT(!swizzleRequired); 238 ASSERT(mipLevels == 1 || mipLevels == mMipLevels); 239 } 240 241 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 242 { 243 // We must ensure that the level zero texture is in sync with mipped texture. 244 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); 245 } 246 247 if (swizzleRequired) 248 { 249 verifySwizzleExists(GetEffectiveSwizzle(textureState)); 250 } 251 252 // We drop the stencil when sampling from the SRV if three conditions hold: 253 // 1. the drop stencil workaround is enabled. 254 const bool emulateTinyStencilTextures = 255 mRenderer->getFeatures().emulateTinyStencilTextures.enabled; 256 // 2. this is a stencil texture. 257 const bool hasStencil = (mFormatInfo.format().stencilBits > 0); 258 // 3. the texture has a 1x1 or 2x2 mip. 259 const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1; 260 const bool hasSmallMips = 261 (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2); 262 263 const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips); 264 const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil); 265 if (useDropStencil) 266 { 267 // Ensure drop texture gets created. 268 DropStencil result = DropStencil::CREATED; 269 ANGLE_TRY(ensureDropStencilTexture(context, &result)); 270 271 // Clear the SRV cache if necessary. 272 // TODO(jmadill): Re-use find query result. 273 const auto srvEntry = mSrvCacheForSampler.find(key); 274 if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end()) 275 { 276 mSrvCacheForSampler.erase(key); 277 } 278 } 279 280 ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV)); 281 282 return angle::Result::Continue; 283 } 284 285 angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context, 286 const SamplerKey &key, 287 const d3d11::SharedSRV **outSRV) 288 { 289 auto iter = mSrvCacheForSampler.find(key); 290 if (iter != mSrvCacheForSampler.end()) 291 { 292 *outSRV = &iter->second; 293 return angle::Result::Continue; 294 } 295 296 const TextureHelper11 *texture = nullptr; 297 DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; 298 299 if (key.swizzle) 300 { 301 const auto &swizzleFormat = 302 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 303 ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0); 304 ANGLE_TRY(getSwizzleTexture(context, &texture)); 305 format = swizzleFormat.srvFormat; 306 } 307 else if (key.dropStencil) 308 { 309 ASSERT(mDropStencilTexture.valid()); 310 texture = &mDropStencilTexture; 311 format = DXGI_FORMAT_R32_FLOAT; 312 } 313 else 314 { 315 ANGLE_TRY(getResource(context, &texture)); 316 format = mFormatInfo.srvFormat; 317 } 318 319 d3d11::SharedSRV srv; 320 321 ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv)); 322 323 const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv))); 324 *outSRV = &insertIt.first->second; 325 326 return angle::Result::Continue; 327 } 328 329 angle::Result TextureStorage11::getSRVLevel(const gl::Context *context, 330 int mipLevel, 331 SRVType srvType, 332 const d3d11::SharedSRV **outSRV) 333 { 334 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 335 336 ANGLE_TRY(resolveTexture(context)); 337 if (srvType == SRVType::Stencil) 338 { 339 if (!mLevelStencilSRVs[mipLevel].valid()) 340 { 341 const TextureHelper11 *resource = nullptr; 342 ANGLE_TRY(getResource(context, &resource)); 343 344 ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, mFormatInfo.stencilSRVFormat, 345 *resource, &mLevelStencilSRVs[mipLevel])); 346 } 347 *outSRV = &mLevelStencilSRVs[mipLevel]; 348 return angle::Result::Continue; 349 } 350 351 auto &levelSRVs = srvType == SRVType::Blit ? mLevelBlitSRVs : mLevelSRVs; 352 auto &otherLevelSRVs = srvType == SRVType::Blit ? mLevelSRVs : mLevelBlitSRVs; 353 354 if (!levelSRVs[mipLevel].valid()) 355 { 356 // Only create a different SRV for blit if blit format is different from regular srv format 357 if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat) 358 { 359 levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy(); 360 } 361 else 362 { 363 const TextureHelper11 *resource = nullptr; 364 ANGLE_TRY(getResource(context, &resource)); 365 366 DXGI_FORMAT resourceFormat = 367 srvType == SRVType::Blit ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat; 368 ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource, 369 &levelSRVs[mipLevel])); 370 } 371 } 372 373 *outSRV = &levelSRVs[mipLevel]; 374 return angle::Result::Continue; 375 } 376 377 angle::Result TextureStorage11::getSRVLevels(const gl::Context *context, 378 GLint baseLevel, 379 GLint maxLevel, 380 const d3d11::SharedSRV **outSRV) 381 { 382 ANGLE_TRY(resolveTexture(context)); 383 unsigned int mipLevels = maxLevel - baseLevel + 1; 384 385 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, 386 // which corresponds to GL level 0) 387 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel); 388 389 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) 390 { 391 ASSERT(mipLevels == 1 || mipLevels == mMipLevels); 392 } 393 394 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 395 { 396 // We must ensure that the level zero texture is in sync with mipped texture. 397 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); 398 } 399 400 // TODO(jmadill): Assert we don't need to drop stencil. 401 402 SamplerKey key(baseLevel, mipLevels, false, false); 403 ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV)); 404 405 return angle::Result::Continue; 406 } 407 408 angle::Result TextureStorage11::getSRVForImage(const gl::Context *context, 409 const gl::ImageUnit &imageUnit, 410 const d3d11::SharedSRV **outSRV) 411 { 412 ANGLE_TRY(resolveTexture(context)); 413 // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required. 414 ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access, 415 imageUnit.format); 416 ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV)); 417 return angle::Result::Continue; 418 } 419 420 angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context, 421 const ImageKey &key, 422 const d3d11::SharedSRV **outSRV) 423 { 424 auto iter = mSrvCacheForImage.find(key); 425 if (iter != mSrvCacheForImage.end()) 426 { 427 *outSRV = &iter->second; 428 return angle::Result::Continue; 429 } 430 const TextureHelper11 *texture = nullptr; 431 ANGLE_TRY(getResource(context, &texture)); 432 DXGI_FORMAT format = 433 d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat; 434 d3d11::SharedSRV srv; 435 ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv)); 436 const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv))); 437 *outSRV = &insertIt.first->second; 438 return angle::Result::Continue; 439 } 440 441 angle::Result TextureStorage11::getUAVForImage(const gl::Context *context, 442 const gl::ImageUnit &imageUnit, 443 const d3d11::SharedUAV **outUAV) 444 { 445 ANGLE_TRY(resolveTexture(context)); 446 // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required. 447 ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access, 448 imageUnit.format); 449 ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV)); 450 return angle::Result::Continue; 451 } 452 453 angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context, 454 const ImageKey &key, 455 const d3d11::SharedUAV **outUAV) 456 { 457 auto iter = mUavCacheForImage.find(key); 458 if (iter != mUavCacheForImage.end()) 459 { 460 *outUAV = &iter->second; 461 return angle::Result::Continue; 462 } 463 const TextureHelper11 *texture = nullptr; 464 ANGLE_TRY(getResource(context, &texture)); 465 DXGI_FORMAT format = 466 d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat; 467 ASSERT(format != DXGI_FORMAT_UNKNOWN); 468 d3d11::SharedUAV uav; 469 ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav)); 470 const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav))); 471 *outUAV = &insertIt.first->second; 472 return angle::Result::Continue; 473 } 474 475 const d3d11::Format &TextureStorage11::getFormatSet() const 476 { 477 return mFormatInfo; 478 } 479 480 angle::Result TextureStorage11::generateSwizzles(const gl::Context *context, 481 const gl::TextureState &textureState) 482 { 483 ANGLE_TRY(resolveTexture(context)); 484 gl::SwizzleState swizzleTarget = GetEffectiveSwizzle(textureState); 485 for (int level = 0; level < getLevelCount(); level++) 486 { 487 // Check if the swizzle for this level is out of date 488 if (mSwizzleCache[level] != swizzleTarget) 489 { 490 // Need to re-render the swizzle for this level 491 const d3d11::SharedSRV *sourceSRV = nullptr; 492 ANGLE_TRY(getSRVLevel(context, level, 493 textureState.isStencilMode() ? SRVType::Stencil : SRVType::Blit, 494 &sourceSRV)); 495 496 const d3d11::RenderTargetView *destRTV; 497 ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV)); 498 499 gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); 500 501 Blit11 *blitter = mRenderer->getBlitter(); 502 503 ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget)); 504 505 mSwizzleCache[level] = swizzleTarget; 506 } 507 } 508 509 return angle::Result::Continue; 510 } 511 512 void TextureStorage11::markLevelDirty(int mipLevel) 513 { 514 if (mipLevel >= 0 && static_cast<size_t>(mipLevel) < mSwizzleCache.size()) 515 { 516 // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is 517 // not a valid swizzle combination 518 if (mSwizzleCache[mipLevel] != gl::SwizzleState()) 519 { 520 // TODO(jmadill): Invalidate specific swizzle. 521 mRenderer->getStateManager()->invalidateSwizzles(); 522 mSwizzleCache[mipLevel] = gl::SwizzleState(); 523 } 524 } 525 526 if (mDropStencilTexture.valid()) 527 { 528 mDropStencilTexture.reset(); 529 } 530 } 531 532 void TextureStorage11::markDirty() 533 { 534 for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel) 535 { 536 markLevelDirty(static_cast<int>(mipLevel)); 537 } 538 } 539 540 angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context, 541 const TextureHelper11 &srcTexture, 542 unsigned int sourceSubresource, 543 const gl::ImageIndex &index, 544 const gl::Box ©Area) 545 { 546 ASSERT(srcTexture.valid()); 547 548 ANGLE_TRY(resolveTexture(context)); 549 const GLint level = index.getLevelIndex(); 550 551 markLevelDirty(level); 552 553 gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); 554 555 bool fullCopy = copyArea.coversSameExtent(texSize); 556 557 const TextureHelper11 *dstTexture = nullptr; 558 559 // If the zero-LOD workaround is active and we want to update a level greater than zero, then we 560 // should update the mipmapped texture, even if mapmaps are currently disabled. 561 if (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 562 { 563 ANGLE_TRY(getMippedResource(context, &dstTexture)); 564 } 565 else 566 { 567 ANGLE_TRY(getResource(context, &dstTexture)); 568 } 569 570 unsigned int dstSubresource = 0; 571 ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource)); 572 573 ASSERT(dstTexture->valid()); 574 575 const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = 576 d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat); 577 if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) 578 { 579 // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead 580 Blit11 *blitter = mRenderer->getBlitter(); 581 return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize, 582 *dstTexture, dstSubresource, copyArea, texSize, nullptr); 583 } 584 585 D3D11_BOX srcBox; 586 srcBox.left = copyArea.x; 587 srcBox.top = copyArea.y; 588 srcBox.right = 589 copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth); 590 srcBox.bottom = 591 copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight); 592 srcBox.front = copyArea.z; 593 srcBox.back = copyArea.z + copyArea.depth; 594 595 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 596 597 deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y, 598 copyArea.z, srcTexture.get(), sourceSubresource, 599 fullCopy ? nullptr : &srcBox); 600 return angle::Result::Continue; 601 } 602 603 angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context, 604 const TextureHelper11 &dstTexture, 605 unsigned int dstSubresource, 606 const gl::ImageIndex &index, 607 const gl::Box ®ion) 608 { 609 ASSERT(dstTexture.valid()); 610 611 ANGLE_TRY(resolveTexture(context)); 612 const TextureHelper11 *srcTexture = nullptr; 613 614 // If the zero-LOD workaround is active and we want to update a level greater than zero, then we 615 // should update the mipmapped texture, even if mapmaps are currently disabled. 616 if (index.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 617 { 618 ANGLE_TRY(getMippedResource(context, &srcTexture)); 619 } 620 else 621 { 622 ANGLE_TRY(getResource(context, &srcTexture)); 623 } 624 625 ASSERT(srcTexture->valid()); 626 627 unsigned int srcSubresource = 0; 628 ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource)); 629 630 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 631 632 // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox 633 // should be nullptr. 634 D3D11_BOX srcBox; 635 D3D11_BOX *pSrcBox = nullptr; 636 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) 637 { 638 GLsizei width = region.width; 639 GLsizei height = region.height; 640 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr); 641 642 // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures. 643 if (width == region.width && height == region.height) 644 { 645 // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless 646 // the source box is specified. This is okay, since we don't perform 647 // CopySubresourceRegion on depth/stencil textures on 9_3. 648 ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN); 649 srcBox.left = region.x; 650 srcBox.right = region.x + region.width; 651 srcBox.top = region.y; 652 srcBox.bottom = region.y + region.height; 653 srcBox.front = region.z; 654 srcBox.back = region.z + region.depth; 655 pSrcBox = &srcBox; 656 } 657 } 658 659 deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y, 660 region.z, srcTexture->get(), srcSubresource, pSrcBox); 661 662 return angle::Result::Continue; 663 } 664 665 angle::Result TextureStorage11::generateMipmap(const gl::Context *context, 666 const gl::ImageIndex &sourceIndex, 667 const gl::ImageIndex &destIndex) 668 { 669 ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex()); 670 671 ANGLE_TRY(resolveTexture(context)); 672 markLevelDirty(destIndex.getLevelIndex()); 673 674 RenderTargetD3D *source = nullptr; 675 ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source)); 676 677 // dest will always have 0 since, we have just released the MS Texture struct 678 RenderTargetD3D *dest = nullptr; 679 ANGLE_TRY(getRenderTarget(context, destIndex, 0, &dest)); 680 681 RenderTarget11 *srcRT11 = GetAs<RenderTarget11>(source); 682 RenderTarget11 *dstRT11 = GetAs<RenderTarget11>(dest); 683 const d3d11::RenderTargetView &destRTV = dstRT11->getRenderTargetView(); 684 const d3d11::SharedSRV *sourceSRV; 685 ANGLE_TRY(srcRT11->getBlitShaderResourceView(context, &sourceSRV)); 686 687 gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); 688 gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); 689 690 gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth()); 691 gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); 692 693 Blit11 *blitter = mRenderer->getBlitter(); 694 const gl::InternalFormat &sourceInternalFormat = 695 gl::GetSizedInternalFormatInfo(source->getInternalFormat()); 696 GLenum format = sourceInternalFormat.format; 697 GLenum type = sourceInternalFormat.type; 698 return blitter->copyTexture(context, *sourceSRV, sourceArea, sourceSize, format, destRTV, 699 destArea, destSize, nullptr, format, type, GL_LINEAR, false, false, 700 false); 701 } 702 703 void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState) 704 { 705 for (unsigned int level = 0; level < mMipLevels; level++) 706 { 707 ASSERT(mSwizzleCache[level] == swizzleState); 708 } 709 } 710 711 void TextureStorage11::clearSRVCache() 712 { 713 markDirty(); 714 mSrvCacheForSampler.clear(); 715 716 for (size_t level = 0; level < mLevelSRVs.size(); level++) 717 { 718 mLevelSRVs[level].reset(); 719 mLevelBlitSRVs[level].reset(); 720 } 721 } 722 723 angle::Result TextureStorage11::copyToStorage(const gl::Context *context, 724 TextureStorage *destStorage) 725 { 726 ASSERT(destStorage); 727 728 ANGLE_TRY(resolveTexture(context)); 729 const TextureHelper11 *sourceResouce = nullptr; 730 ANGLE_TRY(getResource(context, &sourceResouce)); 731 732 TextureStorage11 *dest11 = GetAs<TextureStorage11>(destStorage); 733 const TextureHelper11 *destResource = nullptr; 734 ANGLE_TRY(dest11->getResource(context, &destResource)); 735 736 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 737 immediateContext->CopyResource(destResource->get(), sourceResouce->get()); 738 739 dest11->markDirty(); 740 741 return angle::Result::Continue; 742 } 743 744 void TextureStorage11::invalidateTextures() 745 { 746 mRenderer->getStateManager()->invalidateTexturesAndSamplers(); 747 } 748 749 angle::Result TextureStorage11::setData(const gl::Context *context, 750 const gl::ImageIndex &index, 751 ImageD3D *image, 752 const gl::Box *destBox, 753 GLenum type, 754 const gl::PixelUnpackState &unpack, 755 const uint8_t *pixelData) 756 { 757 ASSERT(!image->isDirty()); 758 759 ANGLE_TRY(resolveTexture(context)); 760 markLevelDirty(index.getLevelIndex()); 761 762 const TextureHelper11 *resource = nullptr; 763 ANGLE_TRY(getResource(context, &resource)); 764 ASSERT(resource && resource->valid()); 765 766 UINT destSubresource = 0; 767 ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource)); 768 769 const gl::InternalFormat &internalFormatInfo = 770 gl::GetInternalFormatInfo(image->getInternalFormat(), type); 771 772 gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()), 773 getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex())); 774 bool fullUpdate = (destBox == nullptr || *destBox == levelBox); 775 ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); 776 777 // TODO(jmadill): Handle compressed formats 778 // Compressed formats have different load syntax, so we'll have to handle them with slightly 779 // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData 780 // with compressed formats in the calling logic. 781 ASSERT(!internalFormatInfo.compressed); 782 783 Context11 *context11 = GetImplAs<Context11>(context); 784 785 const int width = destBox ? destBox->width : static_cast<int>(image->getWidth()); 786 const int height = destBox ? destBox->height : static_cast<int>(image->getHeight()); 787 const int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth()); 788 GLuint srcRowPitch = 0; 789 ANGLE_CHECK_GL_MATH(context11, 790 internalFormatInfo.computeRowPitch(type, width, unpack.alignment, 791 unpack.rowLength, &srcRowPitch)); 792 GLuint srcDepthPitch = 0; 793 ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch( 794 height, unpack.imageHeight, srcRowPitch, &srcDepthPitch)); 795 GLuint srcSkipBytes = 0; 796 ANGLE_CHECK_GL_MATH( 797 context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack, 798 index.usesTex3D(), &srcSkipBytes)); 799 800 const d3d11::Format &d3d11Format = 801 d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); 802 const d3d11::DXGIFormatSize &dxgiFormatInfo = 803 d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat); 804 805 const size_t outputPixelSize = dxgiFormatInfo.pixelBytes; 806 807 UINT bufferRowPitch = static_cast<unsigned int>(outputPixelSize) * width; 808 UINT bufferDepthPitch = bufferRowPitch * height; 809 810 const size_t neededSize = bufferDepthPitch * depth; 811 angle::MemoryBuffer *conversionBuffer = nullptr; 812 const uint8_t *data = nullptr; 813 814 LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type); 815 if (loadFunctionInfo.requiresConversion) 816 { 817 ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer)); 818 loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch, 819 srcDepthPitch, conversionBuffer->data(), bufferRowPitch, 820 bufferDepthPitch); 821 data = conversionBuffer->data(); 822 } 823 else 824 { 825 data = pixelData + srcSkipBytes; 826 bufferRowPitch = srcRowPitch; 827 bufferDepthPitch = srcDepthPitch; 828 } 829 830 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 831 832 if (!fullUpdate) 833 { 834 ASSERT(destBox); 835 836 D3D11_BOX destD3DBox; 837 destD3DBox.left = destBox->x; 838 destD3DBox.right = destBox->x + destBox->width; 839 destD3DBox.top = destBox->y; 840 destD3DBox.bottom = destBox->y + destBox->height; 841 destD3DBox.front = destBox->z; 842 destD3DBox.back = destBox->z + destBox->depth; 843 844 immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data, 845 bufferRowPitch, bufferDepthPitch); 846 } 847 else 848 { 849 immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data, 850 bufferRowPitch, bufferDepthPitch); 851 } 852 853 return angle::Result::Continue; 854 } 855 856 angle::Result TextureStorage11::ensureDropStencilTexture( 857 const gl::Context *context, 858 TextureStorage11::DropStencil *dropStencilOut) 859 { 860 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 861 return angle::Result::Stop; 862 } 863 864 angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context, 865 const gl::ImageIndexIterator &it) 866 { 867 const TextureHelper11 *sourceTexture = nullptr; 868 ANGLE_TRY(getResource(context, &sourceTexture)); 869 870 gl::ImageIndexIterator itCopy = it; 871 872 while (itCopy.hasNext()) 873 { 874 gl::ImageIndex index = itCopy.next(); 875 gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()), 876 getLevelHeight(index.getLevelIndex()), 1); 877 gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1); 878 879 UINT subresource = 0; 880 ANGLE_TRY(getSubresourceIndex(context, index, &subresource)); 881 882 ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil( 883 context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture, 884 subresource, wholeArea, wholeSize, nullptr)); 885 } 886 887 return angle::Result::Continue; 888 } 889 890 angle::Result TextureStorage11::resolveTextureHelper(const gl::Context *context, 891 const TextureHelper11 &texture) 892 { 893 UINT subresourceIndexSS; 894 ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexSS, &subresourceIndexSS)); 895 UINT subresourceIndexMS; 896 ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexMS, &subresourceIndexMS)); 897 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 898 const TextureHelper11 *resource = nullptr; 899 ANGLE_TRY(mMSTexInfo->msTex->getResource(context, &resource)); 900 deviceContext->ResolveSubresource(texture.get(), subresourceIndexSS, resource->get(), 901 subresourceIndexMS, texture.getFormat()); 902 mMSTexInfo->msTextureNeedsResolve = false; 903 return angle::Result::Continue; 904 } 905 906 angle::Result TextureStorage11::releaseMultisampledTexStorageForLevel(size_t level) 907 { 908 if (mMSTexInfo && mMSTexInfo->indexSS.getLevelIndex() == static_cast<int>(level)) 909 { 910 mMSTexInfo->msTex.reset(); 911 onStateChange(angle::SubjectMessage::ContentsChanged); 912 } 913 return angle::Result::Continue; 914 } 915 916 GLsizei TextureStorage11::getRenderToTextureSamples() const 917 { 918 if (mMSTexInfo) 919 { 920 return mMSTexInfo->samples; 921 } 922 return 0; 923 } 924 925 angle::Result TextureStorage11::findMultisampledRenderTarget(const gl::Context *context, 926 const gl::ImageIndex &index, 927 GLsizei samples, 928 RenderTargetD3D **outRT) const 929 { 930 const int level = index.getLevelIndex(); 931 if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() || 932 samples != mMSTexInfo->samples || !mMSTexInfo->msTex) 933 { 934 *outRT = nullptr; 935 return angle::Result::Continue; 936 } 937 RenderTargetD3D *rt; 938 ANGLE_TRY(mMSTexInfo->msTex->findRenderTarget(context, mMSTexInfo->indexMS, samples, &rt)); 939 *outRT = rt; 940 return angle::Result::Continue; 941 } 942 943 angle::Result TextureStorage11::getMultisampledRenderTarget(const gl::Context *context, 944 const gl::ImageIndex &index, 945 GLsizei samples, 946 RenderTargetD3D **outRT) 947 { 948 const int level = index.getLevelIndex(); 949 if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() || 950 samples != mMSTexInfo->samples || !mMSTexInfo->msTex) 951 { 952 // if mMSTexInfo already exists, then we want to resolve and release it 953 // since the mMSTexInfo must be for a different sample count or level 954 ANGLE_TRY(resolveTexture(context)); 955 956 // Now we can create a new object for the correct sample and level 957 GLsizei width = getLevelWidth(level); 958 GLsizei height = getLevelHeight(level); 959 GLenum internalFormat = mFormatInfo.internalFormat; 960 std::unique_ptr<TextureStorage11_2DMultisample> texMS( 961 GetAs<TextureStorage11_2DMultisample>(mRenderer->createTextureStorage2DMultisample( 962 internalFormat, width, height, level, samples, true, mKHRDebugLabel))); 963 964 // make sure multisample object has the blitted information. 965 gl::Rectangle area(0, 0, width, height); 966 RenderTargetD3D *readRenderTarget = nullptr; 967 // use incoming index here since the index will correspond to the single sampled texture 968 ANGLE_TRY(getRenderTarget(context, index, 0, &readRenderTarget)); 969 gl::ImageIndex indexMS = gl::ImageIndex::Make2DMultisample(); 970 RenderTargetD3D *drawRenderTarget = nullptr; 971 ANGLE_TRY(texMS->getRenderTarget(context, indexMS, samples, &drawRenderTarget)); 972 973 // blit SS -> MS 974 // mask: GL_COLOR_BUFFER_BIT, filter: GL_NEAREST 975 ANGLE_TRY(mRenderer->blitRenderbufferRect(context, area, area, 0, 0, readRenderTarget, 976 drawRenderTarget, GL_NEAREST, nullptr, true, 977 false, false)); 978 mMSTexInfo = std::make_unique<MultisampledRenderToTextureInfo>(samples, index, indexMS); 979 mMSTexInfo->msTex = std::move(texMS); 980 } 981 RenderTargetD3D *rt; 982 ANGLE_TRY(mMSTexInfo->msTex->getRenderTarget(context, mMSTexInfo->indexMS, samples, &rt)); 983 // By returning the multisampled render target to the caller, the render target 984 // is expected to be changed so we need to resolve to a single sampled texture 985 // next time resolveTexture is called. 986 mMSTexInfo->msTextureNeedsResolve = true; 987 *outRT = rt; 988 return angle::Result::Continue; 989 } 990 991 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, 992 SwapChain11 *swapchain, 993 const std::string &label) 994 : TextureStorage11(renderer, 995 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 996 0, 997 swapchain->getRenderTargetInternalFormat(), 998 label), 999 mTexture(swapchain->getOffscreenTexture()), 1000 mLevelZeroTexture(), 1001 mLevelZeroRenderTarget(nullptr), 1002 mUseLevelZeroTexture(false), 1003 mSwizzleTexture() 1004 { 1005 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 1006 { 1007 mAssociatedImages[i] = nullptr; 1008 mRenderTarget[i] = nullptr; 1009 } 1010 1011 D3D11_TEXTURE2D_DESC texDesc; 1012 mTexture.getDesc(&texDesc); 1013 mMipLevels = texDesc.MipLevels; 1014 mTextureWidth = texDesc.Width; 1015 mTextureHeight = texDesc.Height; 1016 mTextureDepth = 1; 1017 mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; 1018 } 1019 1020 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, 1021 GLenum internalformat, 1022 BindFlags bindFlags, 1023 GLsizei width, 1024 GLsizei height, 1025 int levels, 1026 const std::string &label, 1027 bool hintLevelZeroOnly) 1028 : TextureStorage11( 1029 renderer, 1030 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), 1031 GetTextureMiscFlags(internalformat, 1032 renderer->getRenderer11DeviceCaps(), 1033 bindFlags, 1034 levels), 1035 internalformat, 1036 label), 1037 mTexture(), 1038 mHasKeyedMutex(false), 1039 mLevelZeroTexture(), 1040 mLevelZeroRenderTarget(nullptr), 1041 mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), 1042 mSwizzleTexture() 1043 { 1044 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 1045 { 1046 mAssociatedImages[i] = nullptr; 1047 mRenderTarget[i] = nullptr; 1048 } 1049 1050 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); 1051 mMipLevels = mTopLevel + levels; 1052 mTextureWidth = width; 1053 mTextureHeight = height; 1054 mTextureDepth = 1; 1055 1056 // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. 1057 ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); 1058 } 1059 1060 void TextureStorage11_2D::onLabelUpdate() 1061 { 1062 if (mTexture.valid()) 1063 { 1064 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 1065 } 1066 if (mLevelZeroTexture.valid()) 1067 { 1068 mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel); 1069 } 1070 if (mSwizzleTexture.valid()) 1071 { 1072 mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); 1073 } 1074 } 1075 1076 angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context) 1077 { 1078 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 1079 { 1080 if (mAssociatedImages[i] != nullptr) 1081 { 1082 mAssociatedImages[i]->verifyAssociatedStorageValid(this); 1083 1084 // We must let the Images recover their data before we delete it from the 1085 // TextureStorage. 1086 ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); 1087 } 1088 } 1089 1090 if (mHasKeyedMutex) 1091 { 1092 // If the keyed mutex is released that will unbind it and cause the state cache to become 1093 // desynchronized. 1094 mRenderer->getStateManager()->invalidateBoundViews(); 1095 } 1096 1097 return angle::Result::Continue; 1098 } 1099 1100 TextureStorage11_2D::~TextureStorage11_2D() {} 1101 1102 angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context, 1103 TextureStorage *destStorage) 1104 { 1105 ASSERT(destStorage); 1106 1107 TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage); 1108 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 1109 1110 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 1111 { 1112 // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the 1113 // corresponding textures in destStorage. 1114 if (mTexture.valid()) 1115 { 1116 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); 1117 1118 const TextureHelper11 *destResource = nullptr; 1119 ANGLE_TRY(dest11->getResource(context, &destResource)); 1120 1121 immediateContext->CopyResource(destResource->get(), mTexture.get()); 1122 } 1123 1124 if (mLevelZeroTexture.valid()) 1125 { 1126 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); 1127 1128 const TextureHelper11 *destResource = nullptr; 1129 ANGLE_TRY(dest11->getResource(context, &destResource)); 1130 1131 immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); 1132 } 1133 1134 return angle::Result::Continue; 1135 } 1136 1137 const TextureHelper11 *sourceResouce = nullptr; 1138 ANGLE_TRY(getResource(context, &sourceResouce)); 1139 1140 const TextureHelper11 *destResource = nullptr; 1141 ANGLE_TRY(dest11->getResource(context, &destResource)); 1142 1143 immediateContext->CopyResource(destResource->get(), sourceResouce->get()); 1144 dest11->markDirty(); 1145 1146 return angle::Result::Continue; 1147 } 1148 1149 angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context, 1150 bool useLevelZeroTexture) 1151 { 1152 if (useLevelZeroTexture && mMipLevels > 1) 1153 { 1154 if (!mUseLevelZeroTexture && mTexture.valid()) 1155 { 1156 ANGLE_TRY(ensureTextureExists(context, 1)); 1157 1158 // Pull data back from the mipped texture if necessary. 1159 ASSERT(mLevelZeroTexture.valid()); 1160 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1161 deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0, 1162 mTexture.get(), 0, nullptr); 1163 } 1164 1165 mUseLevelZeroTexture = true; 1166 } 1167 else 1168 { 1169 if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) 1170 { 1171 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 1172 1173 // Pull data back from the level zero texture if necessary. 1174 ASSERT(mTexture.valid()); 1175 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 1176 deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0, 1177 mLevelZeroTexture.get(), 0, nullptr); 1178 } 1179 1180 mUseLevelZeroTexture = false; 1181 } 1182 1183 return angle::Result::Continue; 1184 } 1185 1186 void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index) 1187 { 1188 const GLint level = index.getLevelIndex(); 1189 1190 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 1191 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 1192 { 1193 mAssociatedImages[level] = image; 1194 } 1195 } 1196 1197 void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index, 1198 Image11 *expectedImage) 1199 { 1200 const GLint level = index.getLevelIndex(); 1201 1202 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 1203 // This validation check should never return false. It means the Image/TextureStorage 1204 // association is broken. 1205 ASSERT(mAssociatedImages[level] == expectedImage); 1206 } 1207 1208 // disassociateImage allows an Image to end its association with a Storage. 1209 void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) 1210 { 1211 const GLint level = index.getLevelIndex(); 1212 1213 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 1214 ASSERT(mAssociatedImages[level] == expectedImage); 1215 mAssociatedImages[level] = nullptr; 1216 } 1217 1218 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image 1219 // recover its data before ending the association. 1220 angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context, 1221 const gl::ImageIndex &index, 1222 Image11 *incomingImage) 1223 { 1224 const GLint level = index.getLevelIndex(); 1225 1226 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 1227 1228 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 1229 { 1230 // No need to let the old Image recover its data, if it is also the incoming Image. 1231 if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) 1232 { 1233 // Ensure that the Image is still associated with this TextureStorage. 1234 mAssociatedImages[level]->verifyAssociatedStorageValid(this); 1235 1236 // Force the image to recover from storage before its data is overwritten. 1237 // This will reset mAssociatedImages[level] to nullptr too. 1238 ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); 1239 } 1240 } 1241 1242 return angle::Result::Continue; 1243 } 1244 1245 angle::Result TextureStorage11_2D::getResource(const gl::Context *context, 1246 const TextureHelper11 **outResource) 1247 { 1248 if (mUseLevelZeroTexture && mMipLevels > 1) 1249 { 1250 ANGLE_TRY(ensureTextureExists(context, 1)); 1251 1252 *outResource = &mLevelZeroTexture; 1253 return angle::Result::Continue; 1254 } 1255 1256 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 1257 1258 *outResource = &mTexture; 1259 return angle::Result::Continue; 1260 } 1261 1262 angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context, 1263 const TextureHelper11 **outResource) 1264 { 1265 // This shouldn't be called unless the zero max LOD workaround is active. 1266 ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); 1267 1268 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 1269 1270 *outResource = &mTexture; 1271 return angle::Result::Continue; 1272 } 1273 1274 angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels) 1275 { 1276 // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. 1277 ANGLE_TRY(resolveTexture(context)); 1278 bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled 1279 ? (mipLevels == 1) && (mMipLevels > 1) 1280 : false; 1281 TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; 1282 1283 // if the width or height is not positive this should be treated as an incomplete texture 1284 // we handle that here by skipping the d3d texture creation 1285 if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) 1286 { 1287 ASSERT(mipLevels > 0); 1288 1289 D3D11_TEXTURE2D_DESC desc; 1290 desc.Width = mTextureWidth; // Compressed texture size constraints? 1291 desc.Height = mTextureHeight; 1292 desc.MipLevels = mipLevels; 1293 desc.ArraySize = 1; 1294 desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; 1295 desc.SampleDesc.Count = 1; 1296 desc.SampleDesc.Quality = 0; 1297 desc.Usage = D3D11_USAGE_DEFAULT; 1298 desc.BindFlags = getBindFlags(); 1299 desc.CPUAccessFlags = 0; 1300 desc.MiscFlags = getMiscFlags(); 1301 1302 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 1303 outputTexture)); 1304 1305 if (useLevelZeroTexture) 1306 { 1307 outputTexture->setLabels("TexStorage2D.Level0Texture", &mKHRDebugLabel); 1308 } 1309 else 1310 { 1311 outputTexture->setLabels("TexStorage2D.Texture", &mKHRDebugLabel); 1312 } 1313 } 1314 1315 return angle::Result::Continue; 1316 } 1317 1318 angle::Result TextureStorage11_2D::findRenderTarget(const gl::Context *context, 1319 const gl::ImageIndex &index, 1320 GLsizei samples, 1321 RenderTargetD3D **outRT) const 1322 { 1323 ASSERT(!index.hasLayer()); 1324 1325 const int level = index.getLevelIndex(); 1326 ASSERT(level >= 0 && level < getLevelCount()); 1327 1328 bool needMS = samples > 0; 1329 if (needMS) 1330 { 1331 return findMultisampledRenderTarget(context, index, samples, outRT); 1332 } 1333 1334 ASSERT(outRT); 1335 if (mRenderTarget[level]) 1336 { 1337 *outRT = mRenderTarget[level].get(); 1338 return angle::Result::Continue; 1339 } 1340 1341 if (mUseLevelZeroTexture) 1342 { 1343 ASSERT(level == 0); 1344 *outRT = mLevelZeroRenderTarget.get(); 1345 return angle::Result::Continue; 1346 } 1347 1348 *outRT = nullptr; 1349 return angle::Result::Continue; 1350 } 1351 1352 angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context, 1353 const gl::ImageIndex &index, 1354 GLsizei samples, 1355 RenderTargetD3D **outRT) 1356 { 1357 ASSERT(!index.hasLayer()); 1358 1359 const int level = index.getLevelIndex(); 1360 ASSERT(level >= 0 && level < getLevelCount()); 1361 1362 bool needMS = samples > 0; 1363 if (needMS) 1364 { 1365 return getMultisampledRenderTarget(context, index, samples, outRT); 1366 } 1367 else 1368 { 1369 ANGLE_TRY(resolveTexture(context)); 1370 } 1371 1372 // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of 1373 // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could 1374 // create RTVs on non-zero levels of the texture (e.g. generateMipmap). 1375 // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the 1376 // individual levels of the texture, so methods like generateMipmap can't do anything useful 1377 // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly 1378 // something wrong. 1379 ASSERT( 1380 !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0)); 1381 ASSERT(outRT); 1382 if (mRenderTarget[level]) 1383 { 1384 *outRT = mRenderTarget[level].get(); 1385 return angle::Result::Continue; 1386 } 1387 1388 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 1389 { 1390 ASSERT(level == 0); 1391 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); 1392 } 1393 1394 const TextureHelper11 *texture = nullptr; 1395 ANGLE_TRY(getResource(context, &texture)); 1396 1397 const d3d11::SharedSRV *srv = nullptr; 1398 ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv)); 1399 1400 const d3d11::SharedSRV *blitSRV = nullptr; 1401 ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV)); 1402 1403 Context11 *context11 = GetImplAs<Context11>(context); 1404 1405 if (mUseLevelZeroTexture) 1406 { 1407 if (!mLevelZeroRenderTarget) 1408 { 1409 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 1410 rtvDesc.Format = mFormatInfo.rtvFormat; 1411 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 1412 rtvDesc.Texture2D.MipSlice = mTopLevel + level; 1413 1414 d3d11::RenderTargetView rtv; 1415 ANGLE_TRY( 1416 mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv)); 1417 rtv.setLabels("TexStorage2D.Level0RTV", &mKHRDebugLabel); 1418 1419 mLevelZeroRenderTarget.reset(new TextureRenderTarget11( 1420 std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), 1421 mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), 1422 getLevelHeight(level), 1, 0)); 1423 } 1424 1425 *outRT = mLevelZeroRenderTarget.get(); 1426 return angle::Result::Continue; 1427 } 1428 1429 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 1430 { 1431 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 1432 rtvDesc.Format = mFormatInfo.rtvFormat; 1433 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 1434 rtvDesc.Texture2D.MipSlice = mTopLevel + level; 1435 1436 d3d11::RenderTargetView rtv; 1437 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); 1438 rtv.setLabels("TexStorage2D.RTV", &mKHRDebugLabel); 1439 1440 mRenderTarget[level].reset(new TextureRenderTarget11( 1441 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), 1442 getLevelWidth(level), getLevelHeight(level), 1, 0)); 1443 1444 *outRT = mRenderTarget[level].get(); 1445 return angle::Result::Continue; 1446 } 1447 1448 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); 1449 1450 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 1451 dsvDesc.Format = mFormatInfo.dsvFormat; 1452 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 1453 dsvDesc.Texture2D.MipSlice = mTopLevel + level; 1454 dsvDesc.Flags = 0; 1455 1456 d3d11::DepthStencilView dsv; 1457 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); 1458 dsv.setLabels("TexStorage2D.DSV", &mKHRDebugLabel); 1459 1460 mRenderTarget[level].reset(new TextureRenderTarget11( 1461 std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), 1462 getLevelWidth(level), getLevelHeight(level), 1, 0)); 1463 1464 *outRT = mRenderTarget[level].get(); 1465 return angle::Result::Continue; 1466 } 1467 1468 angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context, 1469 int baseLevel, 1470 int mipLevels, 1471 DXGI_FORMAT format, 1472 const TextureHelper11 &texture, 1473 d3d11::SharedSRV *outSRV) 1474 { 1475 ASSERT(outSRV); 1476 1477 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 1478 srvDesc.Format = format; 1479 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 1480 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; 1481 srvDesc.Texture2D.MipLevels = mipLevels; 1482 1483 const TextureHelper11 *srvTexture = &texture; 1484 1485 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 1486 { 1487 ASSERT(mTopLevel == 0); 1488 ASSERT(baseLevel == 0); 1489 // This code also assumes that the incoming texture equals either mLevelZeroTexture or 1490 // mTexture. 1491 1492 if (mipLevels == 1 && mMipLevels > 1) 1493 { 1494 // We must use a SRV on the level-zero-only texture. 1495 ANGLE_TRY(ensureTextureExists(context, 1)); 1496 srvTexture = &mLevelZeroTexture; 1497 } 1498 else 1499 { 1500 ASSERT(mipLevels == static_cast<int>(mMipLevels)); 1501 ASSERT(mTexture.valid() && texture == mTexture); 1502 srvTexture = &mTexture; 1503 } 1504 } 1505 1506 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(), 1507 outSRV)); 1508 outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel); 1509 1510 return angle::Result::Continue; 1511 } 1512 1513 angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context, 1514 int level, 1515 DXGI_FORMAT format, 1516 const TextureHelper11 &texture, 1517 d3d11::SharedSRV *outSRV) 1518 { 1519 ASSERT(outSRV); 1520 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 1521 srvDesc.Format = format; 1522 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 1523 srvDesc.Texture2D.MostDetailedMip = mTopLevel + level; 1524 srvDesc.Texture2D.MipLevels = 1; 1525 ANGLE_TRY( 1526 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 1527 outSRV->setLabels("TexStorage2D.SRVForImage", &mKHRDebugLabel); 1528 return angle::Result::Continue; 1529 } 1530 1531 angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context, 1532 int level, 1533 DXGI_FORMAT format, 1534 const TextureHelper11 &texture, 1535 d3d11::SharedUAV *outUAV) 1536 { 1537 ASSERT(outUAV); 1538 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; 1539 uavDesc.Format = format; 1540 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; 1541 uavDesc.Texture2D.MipSlice = mTopLevel + level; 1542 ANGLE_TRY( 1543 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV)); 1544 outUAV->setLabels("TexStorage2D.UAVForImage", &mKHRDebugLabel); 1545 return angle::Result::Continue; 1546 } 1547 1548 angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context, 1549 const TextureHelper11 **outTexture) 1550 { 1551 ASSERT(outTexture); 1552 1553 if (!mSwizzleTexture.valid()) 1554 { 1555 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 1556 1557 D3D11_TEXTURE2D_DESC desc; 1558 desc.Width = mTextureWidth; 1559 desc.Height = mTextureHeight; 1560 desc.MipLevels = mMipLevels; 1561 desc.ArraySize = 1; 1562 desc.Format = format.texFormat; 1563 desc.SampleDesc.Count = 1; 1564 desc.SampleDesc.Quality = 0; 1565 desc.Usage = D3D11_USAGE_DEFAULT; 1566 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 1567 desc.CPUAccessFlags = 0; 1568 desc.MiscFlags = 0; 1569 1570 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format, 1571 &mSwizzleTexture)); 1572 mSwizzleTexture.setLabels("TexStorage2D.SwizzleTexture", &mKHRDebugLabel); 1573 } 1574 1575 *outTexture = &mSwizzleTexture; 1576 return angle::Result::Continue; 1577 } 1578 1579 angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context, 1580 int mipLevel, 1581 const d3d11::RenderTargetView **outRTV) 1582 { 1583 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 1584 ASSERT(outRTV); 1585 1586 if (!mSwizzleRenderTargets[mipLevel].valid()) 1587 { 1588 const TextureHelper11 *swizzleTexture = nullptr; 1589 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); 1590 1591 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 1592 rtvDesc.Format = 1593 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; 1594 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 1595 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; 1596 1597 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 1598 mSwizzleTexture.get(), 1599 &mSwizzleRenderTargets[mipLevel])); 1600 } 1601 1602 *outRTV = &mSwizzleRenderTargets[mipLevel]; 1603 return angle::Result::Continue; 1604 } 1605 1606 angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context, 1607 DropStencil *dropStencilOut) 1608 { 1609 if (mDropStencilTexture.valid()) 1610 { 1611 *dropStencilOut = DropStencil::ALREADY_EXISTS; 1612 return angle::Result::Continue; 1613 } 1614 1615 D3D11_TEXTURE2D_DESC dropDesc = {}; 1616 dropDesc.ArraySize = 1; 1617 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; 1618 dropDesc.CPUAccessFlags = 0; 1619 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; 1620 dropDesc.Height = mTextureHeight; 1621 dropDesc.MipLevels = mMipLevels; 1622 dropDesc.MiscFlags = 0; 1623 dropDesc.SampleDesc.Count = 1; 1624 dropDesc.SampleDesc.Quality = 0; 1625 dropDesc.Usage = D3D11_USAGE_DEFAULT; 1626 dropDesc.Width = mTextureWidth; 1627 1628 const auto &format = 1629 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); 1630 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format, 1631 &mDropStencilTexture)); 1632 mDropStencilTexture.setLabels("TexStorage2D.DropStencil", &mKHRDebugLabel); 1633 1634 ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels))); 1635 1636 *dropStencilOut = DropStencil::CREATED; 1637 return angle::Result::Continue; 1638 } 1639 1640 angle::Result TextureStorage11_2D::resolveTexture(const gl::Context *context) 1641 { 1642 if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve) 1643 { 1644 ANGLE_TRY(resolveTextureHelper(context, mTexture)); 1645 onStateChange(angle::SubjectMessage::ContentsChanged); 1646 } 1647 return angle::Result::Continue; 1648 } 1649 1650 TextureStorage11_External::TextureStorage11_External( 1651 Renderer11 *renderer, 1652 egl::Stream *stream, 1653 const egl::Stream::GLTextureDescription &glDesc, 1654 const std::string &label) 1655 : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label) 1656 { 1657 ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture); 1658 auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation()); 1659 mTexture.set(producer->getD3DTexture(), mFormatInfo); 1660 mSubresourceIndex = producer->getArraySlice(); 1661 mTexture.get()->AddRef(); 1662 mMipLevels = 1; 1663 1664 D3D11_TEXTURE2D_DESC desc; 1665 mTexture.getDesc(&desc); 1666 mTextureWidth = desc.Width; 1667 mTextureHeight = desc.Height; 1668 mTextureDepth = 1; 1669 mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; 1670 } 1671 1672 angle::Result TextureStorage11_External::onDestroy(const gl::Context *context) 1673 { 1674 if (mHasKeyedMutex) 1675 { 1676 // If the keyed mutex is released that will unbind it and cause the state cache to become 1677 // desynchronized. 1678 mRenderer->getStateManager()->invalidateBoundViews(); 1679 } 1680 1681 return angle::Result::Continue; 1682 } 1683 1684 TextureStorage11_External::~TextureStorage11_External() {} 1685 1686 angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context, 1687 TextureStorage *destStorage) 1688 { 1689 UNIMPLEMENTED(); 1690 return angle::Result::Continue; 1691 } 1692 1693 void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index) 1694 { 1695 ASSERT(index.getLevelIndex() == 0); 1696 mAssociatedImage = image; 1697 } 1698 1699 void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index, 1700 Image11 *expectedImage) 1701 { 1702 ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage); 1703 } 1704 1705 void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index, 1706 Image11 *expectedImage) 1707 { 1708 ASSERT(index.getLevelIndex() == 0); 1709 ASSERT(mAssociatedImage == expectedImage); 1710 mAssociatedImage = nullptr; 1711 } 1712 1713 angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context, 1714 const gl::ImageIndex &index, 1715 Image11 *incomingImage) 1716 { 1717 ASSERT(index.getLevelIndex() == 0); 1718 1719 if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage) 1720 { 1721 mAssociatedImage->verifyAssociatedStorageValid(this); 1722 1723 ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context)); 1724 } 1725 1726 return angle::Result::Continue; 1727 } 1728 1729 angle::Result TextureStorage11_External::getResource(const gl::Context *context, 1730 const TextureHelper11 **outResource) 1731 { 1732 *outResource = &mTexture; 1733 return angle::Result::Continue; 1734 } 1735 1736 angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context, 1737 const TextureHelper11 **outResource) 1738 { 1739 *outResource = &mTexture; 1740 return angle::Result::Continue; 1741 } 1742 1743 angle::Result TextureStorage11_External::findRenderTarget(const gl::Context *context, 1744 const gl::ImageIndex &index, 1745 GLsizei samples, 1746 RenderTargetD3D **outRT) const 1747 { 1748 // Render targets are not supported for external textures 1749 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1750 return angle::Result::Stop; 1751 } 1752 1753 angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context, 1754 const gl::ImageIndex &index, 1755 GLsizei samples, 1756 RenderTargetD3D **outRT) 1757 { 1758 // Render targets are not supported for external textures 1759 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1760 return angle::Result::Stop; 1761 } 1762 1763 angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context, 1764 int baseLevel, 1765 int mipLevels, 1766 DXGI_FORMAT format, 1767 const TextureHelper11 &texture, 1768 d3d11::SharedSRV *outSRV) 1769 { 1770 // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and 1771 // use the specified subresource ID the storage was created with. 1772 ASSERT(mipLevels == 1); 1773 ASSERT(outSRV); 1774 1775 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 1776 srvDesc.Format = format; 1777 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 1778 // subresource index is equal to the mip level for 2D textures 1779 srvDesc.Texture2DArray.MostDetailedMip = 0; 1780 srvDesc.Texture2DArray.MipLevels = 1; 1781 srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex; 1782 srvDesc.Texture2DArray.ArraySize = 1; 1783 1784 ANGLE_TRY( 1785 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 1786 outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel); 1787 1788 return angle::Result::Continue; 1789 } 1790 1791 angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context, 1792 int level, 1793 DXGI_FORMAT format, 1794 const TextureHelper11 &texture, 1795 d3d11::SharedSRV *outSRV) 1796 { 1797 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1798 return angle::Result::Stop; 1799 } 1800 1801 angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context, 1802 int level, 1803 DXGI_FORMAT format, 1804 const TextureHelper11 &texture, 1805 d3d11::SharedUAV *outUAV) 1806 { 1807 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1808 return angle::Result::Stop; 1809 } 1810 1811 angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context, 1812 const TextureHelper11 **outTexture) 1813 { 1814 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1815 return angle::Result::Stop; 1816 } 1817 1818 angle::Result TextureStorage11_External::getSwizzleRenderTarget( 1819 const gl::Context *context, 1820 int mipLevel, 1821 const d3d11::RenderTargetView **outRTV) 1822 { 1823 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1824 return angle::Result::Stop; 1825 } 1826 1827 void TextureStorage11_External::onLabelUpdate() 1828 { 1829 if (mTexture.valid()) 1830 { 1831 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 1832 } 1833 } 1834 1835 TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer, 1836 UINT bindFlags, 1837 UINT miscFlags, 1838 GLenum internalFormat, 1839 const std::string &label) 1840 : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat, label) 1841 {} 1842 1843 void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {} 1844 1845 void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {} 1846 1847 void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {} 1848 1849 angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context, 1850 const gl::ImageIndex &, 1851 Image11 *) 1852 { 1853 return angle::Result::Continue; 1854 } 1855 1856 angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context, 1857 int level, 1858 DXGI_FORMAT format, 1859 const TextureHelper11 &texture, 1860 d3d11::SharedSRV *outSRV) 1861 { 1862 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1863 return angle::Result::Stop; 1864 } 1865 1866 angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context, 1867 int level, 1868 DXGI_FORMAT format, 1869 const TextureHelper11 &texture, 1870 d3d11::SharedUAV *outUAV) 1871 { 1872 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1873 return angle::Result::Stop; 1874 } 1875 1876 TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, 1877 EGLImageD3D *eglImage, 1878 RenderTarget11 *renderTarget11, 1879 const std::string &label) 1880 : TextureStorage11ImmutableBase(renderer, 1881 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 1882 0, 1883 renderTarget11->getInternalFormat(), 1884 label), 1885 mImage(eglImage), 1886 mCurrentRenderTarget(0), 1887 mSwizzleTexture(), 1888 mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 1889 { 1890 mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11); 1891 1892 mMipLevels = 1; 1893 mTextureWidth = renderTarget11->getWidth(); 1894 mTextureHeight = renderTarget11->getHeight(); 1895 mTextureDepth = 1; 1896 } 1897 1898 TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {} 1899 1900 angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context, 1901 const gl::ImageIndex &index, 1902 UINT *outSubresourceIndex) const 1903 { 1904 ASSERT(index.getType() == gl::TextureType::_2D); 1905 ASSERT(index.getLevelIndex() == 0); 1906 1907 RenderTarget11 *renderTarget11 = nullptr; 1908 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); 1909 *outSubresourceIndex = renderTarget11->getSubresourceIndex(); 1910 return angle::Result::Continue; 1911 } 1912 1913 angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context, 1914 const TextureHelper11 **outResource) 1915 { 1916 ANGLE_TRY(checkForUpdatedRenderTarget(context)); 1917 1918 RenderTarget11 *renderTarget11 = nullptr; 1919 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); 1920 *outResource = &renderTarget11->getTexture(); 1921 return angle::Result::Continue; 1922 } 1923 1924 angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context, 1925 const gl::TextureState &textureState, 1926 const gl::SamplerState &sampler, 1927 const d3d11::SharedSRV **outSRV) 1928 { 1929 ANGLE_TRY(checkForUpdatedRenderTarget(context)); 1930 return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV); 1931 } 1932 1933 angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context, 1934 const TextureHelper11 **) 1935 { 1936 // This shouldn't be called unless the zero max LOD workaround is active. 1937 // EGL images are unavailable in this configuration. 1938 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1939 return angle::Result::Stop; 1940 } 1941 1942 angle::Result TextureStorage11_EGLImage::findRenderTarget(const gl::Context *context, 1943 const gl::ImageIndex &index, 1944 GLsizei samples, 1945 RenderTargetD3D **outRT) const 1946 { 1947 // Since the render target of an EGL image will be updated when orphaning, trying to find a 1948 // cache of it can be rarely useful. 1949 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1950 return angle::Result::Stop; 1951 } 1952 1953 angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context, 1954 const gl::ImageIndex &index, 1955 GLsizei samples, 1956 RenderTargetD3D **outRT) 1957 { 1958 ASSERT(!index.hasLayer()); 1959 ASSERT(index.getLevelIndex() == 0); 1960 1961 ANGLE_TRY(checkForUpdatedRenderTarget(context)); 1962 1963 return mImage->getRenderTarget(context, outRT); 1964 } 1965 1966 angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context, 1967 TextureStorage *destStorage) 1968 { 1969 const TextureHelper11 *sourceResouce = nullptr; 1970 ANGLE_TRY(getResource(context, &sourceResouce)); 1971 1972 ASSERT(destStorage); 1973 TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage); 1974 const TextureHelper11 *destResource = nullptr; 1975 ANGLE_TRY(dest11->getResource(context, &destResource)); 1976 1977 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 1978 immediateContext->CopyResource(destResource->get(), sourceResouce->get()); 1979 1980 dest11->markDirty(); 1981 1982 return angle::Result::Continue; 1983 } 1984 1985 angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context, 1986 bool) 1987 { 1988 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 1989 return angle::Result::Stop; 1990 } 1991 1992 angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context, 1993 const TextureHelper11 **outTexture) 1994 { 1995 ASSERT(outTexture); 1996 1997 if (!mSwizzleTexture.valid()) 1998 { 1999 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 2000 2001 D3D11_TEXTURE2D_DESC desc; 2002 desc.Width = mTextureWidth; 2003 desc.Height = mTextureHeight; 2004 desc.MipLevels = mMipLevels; 2005 desc.ArraySize = 1; 2006 desc.Format = format.texFormat; 2007 desc.SampleDesc.Count = 1; 2008 desc.SampleDesc.Quality = 0; 2009 desc.Usage = D3D11_USAGE_DEFAULT; 2010 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 2011 desc.CPUAccessFlags = 0; 2012 desc.MiscFlags = 0; 2013 2014 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format, 2015 &mSwizzleTexture)); 2016 mSwizzleTexture.setLabels("TexStorageEGLImage.SwizzleTexture", &mKHRDebugLabel); 2017 } 2018 2019 *outTexture = &mSwizzleTexture; 2020 return angle::Result::Continue; 2021 } 2022 2023 angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget( 2024 const gl::Context *context, 2025 int mipLevel, 2026 const d3d11::RenderTargetView **outRTV) 2027 { 2028 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 2029 ASSERT(outRTV); 2030 2031 if (!mSwizzleRenderTargets[mipLevel].valid()) 2032 { 2033 const TextureHelper11 *swizzleTexture = nullptr; 2034 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); 2035 2036 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 2037 rtvDesc.Format = 2038 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; 2039 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 2040 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; 2041 2042 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 2043 mSwizzleTexture.get(), 2044 &mSwizzleRenderTargets[mipLevel])); 2045 } 2046 2047 *outRTV = &mSwizzleRenderTargets[mipLevel]; 2048 return angle::Result::Continue; 2049 } 2050 2051 angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context) 2052 { 2053 RenderTarget11 *renderTarget11 = nullptr; 2054 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); 2055 2056 if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11)) 2057 { 2058 clearSRVCache(); 2059 mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11); 2060 } 2061 2062 return angle::Result::Continue; 2063 } 2064 2065 angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context, 2066 int baseLevel, 2067 int mipLevels, 2068 DXGI_FORMAT format, 2069 const TextureHelper11 &texture, 2070 d3d11::SharedSRV *outSRV) 2071 { 2072 ASSERT(baseLevel == 0); 2073 ASSERT(mipLevels == 1); 2074 ASSERT(outSRV); 2075 2076 // Create a new SRV only for the swizzle texture. Otherwise just return the Image's 2077 // RenderTarget's SRV. 2078 if (texture == mSwizzleTexture) 2079 { 2080 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 2081 srvDesc.Format = format; 2082 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 2083 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; 2084 srvDesc.Texture2D.MipLevels = mipLevels; 2085 2086 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), 2087 outSRV)); 2088 outSRV->setLabels("TexStorageEGLImage.SRV", &mKHRDebugLabel); 2089 } 2090 else 2091 { 2092 RenderTarget11 *renderTarget = nullptr; 2093 ANGLE_TRY(getImageRenderTarget(context, &renderTarget)); 2094 2095 ASSERT(texture == renderTarget->getTexture()); 2096 2097 const d3d11::SharedSRV *srv; 2098 ANGLE_TRY(renderTarget->getShaderResourceView(context, &srv)); 2099 2100 *outSRV = srv->makeCopy(); 2101 } 2102 2103 return angle::Result::Continue; 2104 } 2105 2106 angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context, 2107 RenderTarget11 **outRT) const 2108 { 2109 RenderTargetD3D *renderTargetD3D = nullptr; 2110 ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D)); 2111 *outRT = GetAs<RenderTarget11>(renderTargetD3D); 2112 return angle::Result::Continue; 2113 } 2114 2115 void TextureStorage11_EGLImage::onLabelUpdate() 2116 { 2117 if (mSwizzleTexture.valid()) 2118 { 2119 mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); 2120 } 2121 } 2122 2123 TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, 2124 GLenum internalformat, 2125 BindFlags bindFlags, 2126 int size, 2127 int levels, 2128 bool hintLevelZeroOnly, 2129 const std::string &label) 2130 : TextureStorage11( 2131 renderer, 2132 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), 2133 GetTextureMiscFlags(internalformat, 2134 renderer->getRenderer11DeviceCaps(), 2135 bindFlags, 2136 levels), 2137 internalformat, 2138 label), 2139 mTexture(), 2140 mLevelZeroTexture(), 2141 mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), 2142 mSwizzleTexture() 2143 { 2144 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) 2145 { 2146 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) 2147 { 2148 mAssociatedImages[face][level] = nullptr; 2149 mRenderTarget[face][level] = nullptr; 2150 } 2151 } 2152 2153 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) 2154 { 2155 mLevelZeroRenderTarget[face] = nullptr; 2156 } 2157 2158 // adjust size if needed for compressed textures 2159 int height = size; 2160 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel); 2161 2162 mMipLevels = mTopLevel + levels; 2163 mTextureWidth = size; 2164 mTextureHeight = size; 2165 mTextureDepth = 1; 2166 2167 // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. 2168 ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); 2169 } 2170 2171 angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context) 2172 { 2173 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) 2174 { 2175 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++) 2176 { 2177 if (mAssociatedImages[face][level] != nullptr) 2178 { 2179 mAssociatedImages[face][level]->verifyAssociatedStorageValid(this); 2180 2181 // We must let the Images recover their data before we delete it from the 2182 // TextureStorage. 2183 ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context)); 2184 } 2185 } 2186 } 2187 2188 return angle::Result::Continue; 2189 } 2190 2191 TextureStorage11_Cube::~TextureStorage11_Cube() {} 2192 2193 angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context, 2194 const gl::ImageIndex &index, 2195 UINT *outSubresourceIndex) const 2196 { 2197 UINT arraySlice = index.cubeMapFaceIndex(); 2198 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture && 2199 index.getLevelIndex() == 0) 2200 { 2201 UINT subresource = D3D11CalcSubresource(0, arraySlice, 1); 2202 ASSERT(subresource != std::numeric_limits<UINT>::max()); 2203 *outSubresourceIndex = subresource; 2204 } 2205 else 2206 { 2207 UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel); 2208 UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); 2209 ASSERT(subresource != std::numeric_limits<UINT>::max()); 2210 *outSubresourceIndex = subresource; 2211 } 2212 return angle::Result::Continue; 2213 } 2214 2215 angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context, 2216 TextureStorage *destStorage) 2217 { 2218 ASSERT(destStorage); 2219 2220 TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage); 2221 2222 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 2223 { 2224 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 2225 2226 // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the 2227 // corresponding textures in destStorage. 2228 if (mTexture.valid()) 2229 { 2230 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); 2231 2232 const TextureHelper11 *destResource = nullptr; 2233 ANGLE_TRY(dest11->getResource(context, &destResource)); 2234 2235 immediateContext->CopyResource(destResource->get(), mTexture.get()); 2236 } 2237 2238 if (mLevelZeroTexture.valid()) 2239 { 2240 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); 2241 2242 const TextureHelper11 *destResource = nullptr; 2243 ANGLE_TRY(dest11->getResource(context, &destResource)); 2244 2245 immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); 2246 } 2247 } 2248 else 2249 { 2250 const TextureHelper11 *sourceResouce = nullptr; 2251 ANGLE_TRY(getResource(context, &sourceResouce)); 2252 2253 const TextureHelper11 *destResource = nullptr; 2254 ANGLE_TRY(dest11->getResource(context, &destResource)); 2255 2256 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); 2257 immediateContext->CopyResource(destResource->get(), sourceResouce->get()); 2258 } 2259 2260 dest11->markDirty(); 2261 2262 return angle::Result::Continue; 2263 } 2264 2265 angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context, 2266 bool useLevelZeroTexture) 2267 { 2268 if (useLevelZeroTexture && mMipLevels > 1) 2269 { 2270 if (!mUseLevelZeroTexture && mTexture.valid()) 2271 { 2272 ANGLE_TRY(ensureTextureExists(context, 1)); 2273 2274 // Pull data back from the mipped texture if necessary. 2275 ASSERT(mLevelZeroTexture.valid()); 2276 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 2277 2278 for (int face = 0; face < 6; face++) 2279 { 2280 deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 2281 D3D11CalcSubresource(0, face, 1), 0, 0, 0, 2282 mTexture.get(), face * mMipLevels, nullptr); 2283 } 2284 } 2285 2286 mUseLevelZeroTexture = true; 2287 } 2288 else 2289 { 2290 if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) 2291 { 2292 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 2293 2294 // Pull data back from the level zero texture if necessary. 2295 ASSERT(mTexture.valid()); 2296 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); 2297 2298 for (int face = 0; face < 6; face++) 2299 { 2300 deviceContext->CopySubresourceRegion(mTexture.get(), 2301 D3D11CalcSubresource(0, face, mMipLevels), 0, 2302 0, 0, mLevelZeroTexture.get(), face, nullptr); 2303 } 2304 } 2305 2306 mUseLevelZeroTexture = false; 2307 } 2308 2309 return angle::Result::Continue; 2310 } 2311 2312 void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index) 2313 { 2314 const GLint level = index.getLevelIndex(); 2315 const GLint layerTarget = index.cubeMapFaceIndex(); 2316 2317 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2318 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)); 2319 2320 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2321 { 2322 if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)) 2323 { 2324 mAssociatedImages[layerTarget][level] = image; 2325 } 2326 } 2327 } 2328 2329 void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index, 2330 Image11 *expectedImage) 2331 { 2332 const GLint level = index.getLevelIndex(); 2333 const GLint layerTarget = index.cubeMapFaceIndex(); 2334 2335 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2336 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)); 2337 // This validation check should never return false. It means the Image/TextureStorage 2338 // association is broken. 2339 ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); 2340 } 2341 2342 // disassociateImage allows an Image to end its association with a Storage. 2343 void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) 2344 { 2345 const GLint level = index.getLevelIndex(); 2346 const GLint layerTarget = index.cubeMapFaceIndex(); 2347 2348 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2349 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)); 2350 ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); 2351 mAssociatedImages[layerTarget][level] = nullptr; 2352 } 2353 2354 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image 2355 // recover its data before ending the association. 2356 angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context, 2357 const gl::ImageIndex &index, 2358 Image11 *incomingImage) 2359 { 2360 const GLint level = index.getLevelIndex(); 2361 const GLint layerTarget = index.cubeMapFaceIndex(); 2362 2363 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2364 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)); 2365 2366 if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 2367 { 2368 if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount)) 2369 { 2370 // No need to let the old Image recover its data, if it is also the incoming Image. 2371 if (mAssociatedImages[layerTarget][level] != nullptr && 2372 mAssociatedImages[layerTarget][level] != incomingImage) 2373 { 2374 // Ensure that the Image is still associated with this TextureStorage. 2375 mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this); 2376 2377 // Force the image to recover from storage before its data is overwritten. 2378 // This will reset mAssociatedImages[level] to nullptr too. 2379 ANGLE_TRY( 2380 mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context)); 2381 } 2382 } 2383 } 2384 2385 return angle::Result::Continue; 2386 } 2387 2388 angle::Result TextureStorage11_Cube::getResource(const gl::Context *context, 2389 const TextureHelper11 **outResource) 2390 { 2391 if (mUseLevelZeroTexture && mMipLevels > 1) 2392 { 2393 ANGLE_TRY(ensureTextureExists(context, 1)); 2394 *outResource = &mLevelZeroTexture; 2395 } 2396 else 2397 { 2398 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 2399 *outResource = &mTexture; 2400 } 2401 return angle::Result::Continue; 2402 } 2403 2404 angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context, 2405 const TextureHelper11 **outResource) 2406 { 2407 // This shouldn't be called unless the zero max LOD workaround is active. 2408 ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled); 2409 2410 ANGLE_TRY(ensureTextureExists(context, mMipLevels)); 2411 *outResource = &mTexture; 2412 return angle::Result::Continue; 2413 } 2414 2415 angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels) 2416 { 2417 // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. 2418 ANGLE_TRY(resolveTexture(context)); 2419 bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled 2420 ? (mipLevels == 1) && (mMipLevels > 1) 2421 : false; 2422 TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; 2423 2424 // if the size is not positive this should be treated as an incomplete texture 2425 // we handle that here by skipping the d3d texture creation 2426 if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) 2427 { 2428 ASSERT(mMipLevels > 0); 2429 2430 D3D11_TEXTURE2D_DESC desc; 2431 desc.Width = mTextureWidth; 2432 desc.Height = mTextureHeight; 2433 desc.MipLevels = mipLevels; 2434 desc.ArraySize = gl::kCubeFaceCount; 2435 desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; 2436 desc.SampleDesc.Count = 1; 2437 desc.SampleDesc.Quality = 0; 2438 desc.Usage = D3D11_USAGE_DEFAULT; 2439 desc.BindFlags = getBindFlags(); 2440 desc.CPUAccessFlags = 0; 2441 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags(); 2442 2443 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 2444 outputTexture)); 2445 outputTexture->setLabels("TexStorageCube.Texture", &mKHRDebugLabel); 2446 } 2447 2448 return angle::Result::Continue; 2449 } 2450 2451 angle::Result TextureStorage11_Cube::findRenderTarget(const gl::Context *context, 2452 const gl::ImageIndex &index, 2453 GLsizei samples, 2454 RenderTargetD3D **outRT) const 2455 { 2456 const int faceIndex = index.cubeMapFaceIndex(); 2457 const int level = index.getLevelIndex(); 2458 2459 ASSERT(level >= 0 && level < getLevelCount()); 2460 ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount)); 2461 2462 bool needMS = samples > 0; 2463 if (needMS) 2464 { 2465 return findMultisampledRenderTarget(context, index, samples, outRT); 2466 } 2467 2468 if (!mRenderTarget[faceIndex][level]) 2469 { 2470 if (mUseLevelZeroTexture) 2471 { 2472 ASSERT(index.getLevelIndex() == 0); 2473 ASSERT(outRT); 2474 *outRT = mLevelZeroRenderTarget[faceIndex].get(); 2475 return angle::Result::Continue; 2476 } 2477 } 2478 2479 ASSERT(outRT); 2480 *outRT = mRenderTarget[faceIndex][level].get(); 2481 return angle::Result::Continue; 2482 } 2483 2484 angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context, 2485 const TextureHelper11 &texture, 2486 const gl::ImageIndex &index, 2487 DXGI_FORMAT resourceFormat, 2488 d3d11::SharedSRV *srv) const 2489 { 2490 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 2491 srvDesc.Format = resourceFormat; 2492 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex(); 2493 srvDesc.Texture2DArray.MipLevels = 1; 2494 srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex(); 2495 srvDesc.Texture2DArray.ArraySize = 1; 2496 2497 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0) 2498 { 2499 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; 2500 } 2501 else 2502 { 2503 // Will be used with Texture2D sampler, not TextureCube 2504 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 2505 } 2506 2507 ANGLE_TRY( 2508 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv)); 2509 return angle::Result::Continue; 2510 } 2511 2512 angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context, 2513 const gl::ImageIndex &index, 2514 GLsizei samples, 2515 RenderTargetD3D **outRT) 2516 { 2517 const int faceIndex = index.cubeMapFaceIndex(); 2518 const int level = index.getLevelIndex(); 2519 2520 ASSERT(level >= 0 && level < getLevelCount()); 2521 ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount)); 2522 2523 bool needMS = samples > 0; 2524 if (needMS) 2525 { 2526 return getMultisampledRenderTarget(context, index, samples, outRT); 2527 } 2528 else 2529 { 2530 ANGLE_TRY(resolveTexture(context)); 2531 } 2532 2533 Context11 *context11 = GetImplAs<Context11>(context); 2534 2535 if (!mRenderTarget[faceIndex][level]) 2536 { 2537 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 2538 { 2539 ASSERT(index.getLevelIndex() == 0); 2540 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); 2541 } 2542 2543 const TextureHelper11 *texture = nullptr; 2544 ANGLE_TRY(getResource(context, &texture)); 2545 2546 if (mUseLevelZeroTexture) 2547 { 2548 if (!mLevelZeroRenderTarget[faceIndex]) 2549 { 2550 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 2551 rtvDesc.Format = mFormatInfo.rtvFormat; 2552 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 2553 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; 2554 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; 2555 rtvDesc.Texture2DArray.ArraySize = 1; 2556 2557 d3d11::RenderTargetView rtv; 2558 ANGLE_TRY( 2559 mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv)); 2560 2561 mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11( 2562 std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), 2563 mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), 2564 getLevelHeight(level), 1, 0)); 2565 } 2566 2567 ASSERT(outRT); 2568 *outRT = mLevelZeroRenderTarget[faceIndex].get(); 2569 return angle::Result::Continue; 2570 } 2571 2572 d3d11::SharedSRV srv; 2573 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); 2574 d3d11::SharedSRV blitSRV; 2575 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) 2576 { 2577 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, 2578 &blitSRV)); 2579 } 2580 else 2581 { 2582 blitSRV = srv.makeCopy(); 2583 } 2584 2585 srv.setLabels("TexStorageCube.RenderTargetSRV", &mKHRDebugLabel); 2586 2587 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 2588 { 2589 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 2590 rtvDesc.Format = mFormatInfo.rtvFormat; 2591 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 2592 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; 2593 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; 2594 rtvDesc.Texture2DArray.ArraySize = 1; 2595 2596 d3d11::RenderTargetView rtv; 2597 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); 2598 rtv.setLabels("TexStorageCube.RenderTargetRTV", &mKHRDebugLabel); 2599 2600 mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( 2601 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), 2602 getLevelWidth(level), getLevelHeight(level), 1, 0)); 2603 } 2604 else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) 2605 { 2606 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 2607 dsvDesc.Format = mFormatInfo.dsvFormat; 2608 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; 2609 dsvDesc.Flags = 0; 2610 dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; 2611 dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; 2612 dsvDesc.Texture2DArray.ArraySize = 1; 2613 2614 d3d11::DepthStencilView dsv; 2615 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); 2616 dsv.setLabels("TexStorageCube.RenderTargetDSV", &mKHRDebugLabel); 2617 2618 mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( 2619 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), 2620 getLevelWidth(level), getLevelHeight(level), 1, 0)); 2621 } 2622 else 2623 { 2624 UNREACHABLE(); 2625 } 2626 } 2627 2628 ASSERT(outRT); 2629 *outRT = mRenderTarget[faceIndex][level].get(); 2630 return angle::Result::Continue; 2631 } 2632 2633 angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context, 2634 int baseLevel, 2635 int mipLevels, 2636 DXGI_FORMAT format, 2637 const TextureHelper11 &texture, 2638 d3d11::SharedSRV *outSRV) 2639 { 2640 ASSERT(outSRV); 2641 2642 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 2643 srvDesc.Format = format; 2644 2645 // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2646 // 2D textures 2647 const GLenum componentType = d3d11::GetComponentType(format); 2648 if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) 2649 { 2650 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 2651 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; 2652 srvDesc.Texture2DArray.MipLevels = mipLevels; 2653 srvDesc.Texture2DArray.FirstArraySlice = 0; 2654 srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; 2655 } 2656 else 2657 { 2658 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; 2659 srvDesc.TextureCube.MipLevels = mipLevels; 2660 srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; 2661 } 2662 2663 const TextureHelper11 *srvTexture = &texture; 2664 2665 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled) 2666 { 2667 ASSERT(mTopLevel == 0); 2668 ASSERT(baseLevel == 0); 2669 // This code also assumes that the incoming texture equals either mLevelZeroTexture or 2670 // mTexture. 2671 2672 if (mipLevels == 1 && mMipLevels > 1) 2673 { 2674 // We must use a SRV on the level-zero-only texture. 2675 ANGLE_TRY(ensureTextureExists(context, 1)); 2676 srvTexture = &mLevelZeroTexture; 2677 } 2678 else 2679 { 2680 ASSERT(mipLevels == static_cast<int>(mMipLevels)); 2681 ASSERT(mTexture.valid() && texture == mTexture); 2682 srvTexture = &mTexture; 2683 } 2684 } 2685 2686 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(), 2687 outSRV)); 2688 outSRV->setLabels("TexStorageCube.SRV", &mKHRDebugLabel); 2689 2690 return angle::Result::Continue; 2691 } 2692 2693 angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context, 2694 int level, 2695 DXGI_FORMAT format, 2696 const TextureHelper11 &texture, 2697 d3d11::SharedSRV *outSRV) 2698 { 2699 ASSERT(outSRV); 2700 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 2701 srvDesc.Format = format; 2702 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 2703 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; 2704 srvDesc.Texture2DArray.MipLevels = 1; 2705 srvDesc.Texture2DArray.FirstArraySlice = 0; 2706 srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; 2707 ANGLE_TRY( 2708 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 2709 outSRV->setLabels("TexStorageCube.SRVForImage", &mKHRDebugLabel); 2710 return angle::Result::Continue; 2711 } 2712 2713 angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context, 2714 int level, 2715 DXGI_FORMAT format, 2716 const TextureHelper11 &texture, 2717 d3d11::SharedUAV *outUAV) 2718 { 2719 ASSERT(outUAV); 2720 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; 2721 uavDesc.Format = format; 2722 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; 2723 uavDesc.Texture2DArray.MipSlice = mTopLevel + level; 2724 uavDesc.Texture2DArray.FirstArraySlice = 0; 2725 uavDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; 2726 ANGLE_TRY( 2727 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV)); 2728 outUAV->setLabels("TexStorageCube.UAVForImage", &mKHRDebugLabel); 2729 return angle::Result::Continue; 2730 } 2731 2732 angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context, 2733 const TextureHelper11 **outTexture) 2734 { 2735 ASSERT(outTexture); 2736 2737 if (!mSwizzleTexture.valid()) 2738 { 2739 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 2740 2741 D3D11_TEXTURE2D_DESC desc; 2742 desc.Width = mTextureWidth; 2743 desc.Height = mTextureHeight; 2744 desc.MipLevels = mMipLevels; 2745 desc.ArraySize = gl::kCubeFaceCount; 2746 desc.Format = format.texFormat; 2747 desc.SampleDesc.Count = 1; 2748 desc.SampleDesc.Quality = 0; 2749 desc.Usage = D3D11_USAGE_DEFAULT; 2750 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 2751 desc.CPUAccessFlags = 0; 2752 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; 2753 2754 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format, 2755 &mSwizzleTexture)); 2756 mSwizzleTexture.setLabels("TexStorageCube.SwizzleTexture", &mKHRDebugLabel); 2757 } 2758 2759 *outTexture = &mSwizzleTexture; 2760 return angle::Result::Continue; 2761 } 2762 2763 angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context, 2764 int mipLevel, 2765 const d3d11::RenderTargetView **outRTV) 2766 { 2767 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 2768 ASSERT(outRTV); 2769 2770 if (!mSwizzleRenderTargets[mipLevel].valid()) 2771 { 2772 const TextureHelper11 *swizzleTexture = nullptr; 2773 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); 2774 2775 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 2776 rtvDesc.Format = 2777 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; 2778 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 2779 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; 2780 rtvDesc.Texture2DArray.FirstArraySlice = 0; 2781 rtvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount; 2782 2783 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 2784 mSwizzleTexture.get(), 2785 &mSwizzleRenderTargets[mipLevel])); 2786 } 2787 2788 *outRTV = &mSwizzleRenderTargets[mipLevel]; 2789 return angle::Result::Continue; 2790 } 2791 2792 angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context, 2793 DropStencil *dropStencilOut) 2794 { 2795 if (mDropStencilTexture.valid()) 2796 { 2797 *dropStencilOut = DropStencil::ALREADY_EXISTS; 2798 return angle::Result::Continue; 2799 } 2800 2801 D3D11_TEXTURE2D_DESC dropDesc = {}; 2802 dropDesc.ArraySize = 6; 2803 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; 2804 dropDesc.CPUAccessFlags = 0; 2805 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; 2806 dropDesc.Height = mTextureHeight; 2807 dropDesc.MipLevels = mMipLevels; 2808 dropDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; 2809 dropDesc.SampleDesc.Count = 1; 2810 dropDesc.SampleDesc.Quality = 0; 2811 dropDesc.Usage = D3D11_USAGE_DEFAULT; 2812 dropDesc.Width = mTextureWidth; 2813 2814 const auto &format = 2815 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); 2816 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format, 2817 &mDropStencilTexture)); 2818 mDropStencilTexture.setLabels("TexStorageCube.DropStencil", &mKHRDebugLabel); 2819 2820 ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels))); 2821 2822 *dropStencilOut = DropStencil::CREATED; 2823 return angle::Result::Continue; 2824 } 2825 2826 angle::Result TextureStorage11_Cube::resolveTexture(const gl::Context *context) 2827 { 2828 if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve) 2829 { 2830 ANGLE_TRY(resolveTextureHelper(context, mTexture)); 2831 onStateChange(angle::SubjectMessage::ContentsChanged); 2832 } 2833 return angle::Result::Continue; 2834 } 2835 2836 void TextureStorage11_Cube::onLabelUpdate() 2837 { 2838 if (mTexture.valid()) 2839 { 2840 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 2841 } 2842 if (mLevelZeroTexture.valid()) 2843 { 2844 mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel); 2845 } 2846 if (mSwizzleTexture.valid()) 2847 { 2848 mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); 2849 } 2850 } 2851 2852 TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, 2853 GLenum internalformat, 2854 BindFlags bindFlags, 2855 GLsizei width, 2856 GLsizei height, 2857 GLsizei depth, 2858 int levels, 2859 const std::string &label) 2860 : TextureStorage11( 2861 renderer, 2862 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), 2863 GetTextureMiscFlags(internalformat, 2864 renderer->getRenderer11DeviceCaps(), 2865 bindFlags, 2866 levels), 2867 internalformat, 2868 label) 2869 { 2870 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 2871 { 2872 mAssociatedImages[i] = nullptr; 2873 mLevelRenderTargets[i] = nullptr; 2874 } 2875 2876 // adjust size if needed for compressed textures 2877 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); 2878 2879 mMipLevels = mTopLevel + levels; 2880 mTextureWidth = width; 2881 mTextureHeight = height; 2882 mTextureDepth = depth; 2883 } 2884 2885 angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context) 2886 { 2887 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 2888 { 2889 if (mAssociatedImages[i] != nullptr) 2890 { 2891 mAssociatedImages[i]->verifyAssociatedStorageValid(this); 2892 2893 // We must let the Images recover their data before we delete it from the 2894 // TextureStorage. 2895 ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); 2896 } 2897 } 2898 2899 return angle::Result::Continue; 2900 } 2901 2902 TextureStorage11_3D::~TextureStorage11_3D() {} 2903 2904 void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index) 2905 { 2906 const GLint level = index.getLevelIndex(); 2907 2908 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2909 2910 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2911 { 2912 mAssociatedImages[level] = image; 2913 } 2914 } 2915 2916 void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index, 2917 Image11 *expectedImage) 2918 { 2919 const GLint level = index.getLevelIndex(); 2920 2921 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2922 // This validation check should never return false. It means the Image/TextureStorage 2923 // association is broken. 2924 ASSERT(mAssociatedImages[level] == expectedImage); 2925 } 2926 2927 // disassociateImage allows an Image to end its association with a Storage. 2928 void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) 2929 { 2930 const GLint level = index.getLevelIndex(); 2931 2932 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); 2933 ASSERT(mAssociatedImages[level] == expectedImage); 2934 mAssociatedImages[level] = nullptr; 2935 } 2936 2937 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image 2938 // recover its data before ending the association. 2939 angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context, 2940 const gl::ImageIndex &index, 2941 Image11 *incomingImage) 2942 { 2943 const GLint level = index.getLevelIndex(); 2944 2945 ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); 2946 2947 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 2948 { 2949 // No need to let the old Image recover its data, if it is also the incoming Image. 2950 if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) 2951 { 2952 // Ensure that the Image is still associated with this TextureStorage. 2953 mAssociatedImages[level]->verifyAssociatedStorageValid(this); 2954 2955 // Force the image to recover from storage before its data is overwritten. 2956 // This will reset mAssociatedImages[level] to nullptr too. 2957 ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); 2958 } 2959 } 2960 2961 return angle::Result::Continue; 2962 } 2963 2964 angle::Result TextureStorage11_3D::getResource(const gl::Context *context, 2965 const TextureHelper11 **outResource) 2966 { 2967 // If the width, height or depth are not positive this should be treated as an incomplete 2968 // texture. We handle that here by skipping the d3d texture creation. 2969 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) 2970 { 2971 ASSERT(mMipLevels > 0); 2972 2973 D3D11_TEXTURE3D_DESC desc; 2974 desc.Width = mTextureWidth; 2975 desc.Height = mTextureHeight; 2976 desc.Depth = mTextureDepth; 2977 desc.MipLevels = mMipLevels; 2978 desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; 2979 desc.Usage = D3D11_USAGE_DEFAULT; 2980 desc.BindFlags = getBindFlags(); 2981 desc.CPUAccessFlags = 0; 2982 desc.MiscFlags = getMiscFlags(); 2983 2984 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 2985 &mTexture)); 2986 mTexture.setLabels("TexStorage3D.Texture", &mKHRDebugLabel); 2987 } 2988 2989 *outResource = &mTexture; 2990 return angle::Result::Continue; 2991 } 2992 2993 angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context, 2994 int baseLevel, 2995 int mipLevels, 2996 DXGI_FORMAT format, 2997 const TextureHelper11 &texture, 2998 d3d11::SharedSRV *outSRV) 2999 { 3000 ASSERT(outSRV); 3001 3002 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3003 srvDesc.Format = format; 3004 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; 3005 srvDesc.Texture3D.MostDetailedMip = baseLevel; 3006 srvDesc.Texture3D.MipLevels = mipLevels; 3007 3008 ANGLE_TRY( 3009 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 3010 outSRV->setLabels("TexStorage3D.SRV", &mKHRDebugLabel); 3011 3012 return angle::Result::Continue; 3013 } 3014 3015 angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context, 3016 int level, 3017 DXGI_FORMAT format, 3018 const TextureHelper11 &texture, 3019 d3d11::SharedSRV *outSRV) 3020 { 3021 ASSERT(outSRV); 3022 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3023 srvDesc.Format = format; 3024 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; 3025 srvDesc.Texture3D.MostDetailedMip = mTopLevel + level; 3026 srvDesc.Texture3D.MipLevels = 1; 3027 ANGLE_TRY( 3028 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 3029 outSRV->setLabels("TexStorage3D.SRVForImage", &mKHRDebugLabel); 3030 return angle::Result::Continue; 3031 } 3032 3033 angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context, 3034 int level, 3035 DXGI_FORMAT format, 3036 const TextureHelper11 &texture, 3037 d3d11::SharedUAV *outUAV) 3038 { 3039 ASSERT(outUAV); 3040 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; 3041 uavDesc.Format = format; 3042 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; 3043 uavDesc.Texture3D.MipSlice = mTopLevel + level; 3044 uavDesc.Texture3D.FirstWSlice = 0; 3045 uavDesc.Texture3D.WSize = mTextureDepth; 3046 ANGLE_TRY( 3047 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV)); 3048 outUAV->setLabels("TexStorage3D.UAVForImage", &mKHRDebugLabel); 3049 return angle::Result::Continue; 3050 } 3051 3052 angle::Result TextureStorage11_3D::findRenderTarget(const gl::Context *context, 3053 const gl::ImageIndex &index, 3054 GLsizei samples, 3055 RenderTargetD3D **outRT) const 3056 { 3057 const int mipLevel = index.getLevelIndex(); 3058 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3059 3060 if (!index.hasLayer()) 3061 { 3062 ASSERT(outRT); 3063 *outRT = mLevelRenderTargets[mipLevel].get(); 3064 return angle::Result::Continue; 3065 } 3066 3067 const int layer = index.getLayerIndex(); 3068 3069 LevelLayerKey key(mipLevel, layer); 3070 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) 3071 { 3072 ASSERT(outRT); 3073 *outRT = nullptr; 3074 return angle::Result::Continue; 3075 } 3076 3077 ASSERT(outRT); 3078 *outRT = mLevelLayerRenderTargets.at(key).get(); 3079 return angle::Result::Continue; 3080 } 3081 3082 angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context, 3083 const gl::ImageIndex &index, 3084 GLsizei samples, 3085 RenderTargetD3D **outRT) 3086 { 3087 const int mipLevel = index.getLevelIndex(); 3088 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3089 3090 ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); 3091 3092 Context11 *context11 = GetImplAs<Context11>(context); 3093 3094 if (!index.hasLayer()) 3095 { 3096 if (!mLevelRenderTargets[mipLevel]) 3097 { 3098 const TextureHelper11 *texture = nullptr; 3099 ANGLE_TRY(getResource(context, &texture)); 3100 3101 const d3d11::SharedSRV *srv = nullptr; 3102 ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv)); 3103 3104 const d3d11::SharedSRV *blitSRV = nullptr; 3105 ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV)); 3106 3107 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3108 rtvDesc.Format = mFormatInfo.rtvFormat; 3109 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; 3110 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; 3111 rtvDesc.Texture3D.FirstWSlice = 0; 3112 rtvDesc.Texture3D.WSize = static_cast<UINT>(-1); 3113 3114 d3d11::RenderTargetView rtv; 3115 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); 3116 rtv.setLabels("TexStorage3D.RTV", &mKHRDebugLabel); 3117 3118 mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11( 3119 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, 3120 getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), 3121 getLevelDepth(mipLevel), 0)); 3122 } 3123 3124 ASSERT(outRT); 3125 *outRT = mLevelRenderTargets[mipLevel].get(); 3126 return angle::Result::Continue; 3127 } 3128 3129 const int layer = index.getLayerIndex(); 3130 3131 LevelLayerKey key(mipLevel, layer); 3132 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) 3133 { 3134 const TextureHelper11 *texture = nullptr; 3135 ANGLE_TRY(getResource(context, &texture)); 3136 3137 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3138 rtvDesc.Format = mFormatInfo.rtvFormat; 3139 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; 3140 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; 3141 rtvDesc.Texture3D.FirstWSlice = layer; 3142 rtvDesc.Texture3D.WSize = 1; 3143 3144 const d3d11::SharedSRV *srv = nullptr; 3145 ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv)); 3146 3147 const d3d11::SharedSRV *blitSRV = nullptr; 3148 ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV)); 3149 3150 d3d11::RenderTargetView rtv; 3151 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); 3152 rtv.setLabels("TexStorage3D.LayerRTV", &mKHRDebugLabel); 3153 3154 mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11( 3155 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), 3156 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); 3157 } 3158 3159 ASSERT(outRT); 3160 *outRT = mLevelLayerRenderTargets[key].get(); 3161 return angle::Result::Continue; 3162 } 3163 3164 angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context, 3165 const TextureHelper11 **outTexture) 3166 { 3167 ASSERT(outTexture); 3168 3169 if (!mSwizzleTexture.valid()) 3170 { 3171 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 3172 3173 D3D11_TEXTURE3D_DESC desc; 3174 desc.Width = mTextureWidth; 3175 desc.Height = mTextureHeight; 3176 desc.Depth = mTextureDepth; 3177 desc.MipLevels = mMipLevels; 3178 desc.Format = format.texFormat; 3179 desc.Usage = D3D11_USAGE_DEFAULT; 3180 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 3181 desc.CPUAccessFlags = 0; 3182 desc.MiscFlags = 0; 3183 3184 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format, 3185 &mSwizzleTexture)); 3186 mSwizzleTexture.setLabels("TexStorage3D.SwizzleTexture", &mKHRDebugLabel); 3187 } 3188 3189 *outTexture = &mSwizzleTexture; 3190 return angle::Result::Continue; 3191 } 3192 3193 angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context, 3194 int mipLevel, 3195 const d3d11::RenderTargetView **outRTV) 3196 { 3197 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3198 ASSERT(outRTV); 3199 3200 if (!mSwizzleRenderTargets[mipLevel].valid()) 3201 { 3202 const TextureHelper11 *swizzleTexture = nullptr; 3203 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); 3204 3205 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3206 rtvDesc.Format = 3207 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; 3208 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; 3209 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; 3210 rtvDesc.Texture3D.FirstWSlice = 0; 3211 rtvDesc.Texture3D.WSize = static_cast<UINT>(-1); 3212 3213 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 3214 mSwizzleTexture.get(), 3215 &mSwizzleRenderTargets[mipLevel])); 3216 mSwizzleRenderTargets[mipLevel].setLabels("TexStorage3D.SwizzleRTV", &mKHRDebugLabel); 3217 } 3218 3219 *outRTV = &mSwizzleRenderTargets[mipLevel]; 3220 return angle::Result::Continue; 3221 } 3222 3223 void TextureStorage11_3D::onLabelUpdate() 3224 { 3225 if (mTexture.valid()) 3226 { 3227 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 3228 } 3229 if (mSwizzleTexture.valid()) 3230 { 3231 mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); 3232 } 3233 } 3234 3235 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, 3236 GLenum internalformat, 3237 BindFlags bindFlags, 3238 GLsizei width, 3239 GLsizei height, 3240 GLsizei depth, 3241 int levels, 3242 const std::string &label) 3243 : TextureStorage11( 3244 renderer, 3245 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags), 3246 GetTextureMiscFlags(internalformat, 3247 renderer->getRenderer11DeviceCaps(), 3248 bindFlags, 3249 levels), 3250 internalformat, 3251 label) 3252 { 3253 // adjust size if needed for compressed textures 3254 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); 3255 3256 mMipLevels = mTopLevel + levels; 3257 mTextureWidth = width; 3258 mTextureHeight = height; 3259 mTextureDepth = depth; 3260 } 3261 3262 angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context) 3263 { 3264 for (auto iter : mAssociatedImages) 3265 { 3266 if (iter.second) 3267 { 3268 iter.second->verifyAssociatedStorageValid(this); 3269 3270 // We must let the Images recover their data before we delete it from the 3271 // TextureStorage. 3272 ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context)); 3273 } 3274 } 3275 mAssociatedImages.clear(); 3276 3277 return angle::Result::Continue; 3278 } 3279 3280 TextureStorage11_2DArray::~TextureStorage11_2DArray() {} 3281 3282 void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index) 3283 { 3284 const GLint level = index.getLevelIndex(); 3285 const GLint layerTarget = index.getLayerIndex(); 3286 const GLint numLayers = index.getLayerCount(); 3287 3288 ASSERT(0 <= level && level < getLevelCount()); 3289 3290 if (0 <= level && level < getLevelCount()) 3291 { 3292 LevelLayerRangeKey key(level, layerTarget, numLayers); 3293 mAssociatedImages[key] = image; 3294 } 3295 } 3296 3297 void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index, 3298 Image11 *expectedImage) 3299 { 3300 const GLint level = index.getLevelIndex(); 3301 const GLint layerTarget = index.getLayerIndex(); 3302 const GLint numLayers = index.getLayerCount(); 3303 3304 LevelLayerRangeKey key(level, layerTarget, numLayers); 3305 3306 // This validation check should never return false. It means the Image/TextureStorage 3307 // association is broken. 3308 bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && 3309 (mAssociatedImages[key] == expectedImage)); 3310 ASSERT(retValue); 3311 } 3312 3313 // disassociateImage allows an Image to end its association with a Storage. 3314 void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, 3315 Image11 *expectedImage) 3316 { 3317 const GLint level = index.getLevelIndex(); 3318 const GLint layerTarget = index.getLayerIndex(); 3319 const GLint numLayers = index.getLayerCount(); 3320 3321 LevelLayerRangeKey key(level, layerTarget, numLayers); 3322 3323 bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && 3324 (mAssociatedImages[key] == expectedImage)); 3325 ASSERT(imageAssociationCorrect); 3326 mAssociatedImages[key] = nullptr; 3327 } 3328 3329 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image 3330 // recover its data before ending the association. 3331 angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context, 3332 const gl::ImageIndex &index, 3333 Image11 *incomingImage) 3334 { 3335 const GLint level = index.getLevelIndex(); 3336 const GLint layerTarget = index.getLayerIndex(); 3337 const GLint numLayers = index.getLayerCount(); 3338 3339 LevelLayerRangeKey key(level, layerTarget, numLayers); 3340 3341 if (mAssociatedImages.find(key) != mAssociatedImages.end()) 3342 { 3343 if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage) 3344 { 3345 // Ensure that the Image is still associated with this TextureStorage. 3346 mAssociatedImages[key]->verifyAssociatedStorageValid(this); 3347 3348 // Force the image to recover from storage before its data is overwritten. 3349 // This will reset mAssociatedImages[level] to nullptr too. 3350 ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context)); 3351 } 3352 } 3353 3354 return angle::Result::Continue; 3355 } 3356 3357 angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context, 3358 const TextureHelper11 **outResource) 3359 { 3360 // if the width, height or depth is not positive this should be treated as an incomplete texture 3361 // we handle that here by skipping the d3d texture creation 3362 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) 3363 { 3364 ASSERT(mMipLevels > 0); 3365 3366 D3D11_TEXTURE2D_DESC desc; 3367 desc.Width = mTextureWidth; 3368 desc.Height = mTextureHeight; 3369 desc.MipLevels = mMipLevels; 3370 desc.ArraySize = mTextureDepth; 3371 desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat; 3372 desc.SampleDesc.Count = 1; 3373 desc.SampleDesc.Quality = 0; 3374 desc.Usage = D3D11_USAGE_DEFAULT; 3375 desc.BindFlags = getBindFlags(); 3376 desc.CPUAccessFlags = 0; 3377 desc.MiscFlags = getMiscFlags(); 3378 3379 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 3380 &mTexture)); 3381 mTexture.setLabels("TexStorage2DArray.Texture", &mKHRDebugLabel); 3382 } 3383 3384 *outResource = &mTexture; 3385 return angle::Result::Continue; 3386 } 3387 3388 angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context, 3389 int baseLevel, 3390 int mipLevels, 3391 DXGI_FORMAT format, 3392 const TextureHelper11 &texture, 3393 d3d11::SharedSRV *outSRV) 3394 { 3395 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3396 srvDesc.Format = format; 3397 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 3398 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; 3399 srvDesc.Texture2DArray.MipLevels = mipLevels; 3400 srvDesc.Texture2DArray.FirstArraySlice = 0; 3401 srvDesc.Texture2DArray.ArraySize = mTextureDepth; 3402 3403 ANGLE_TRY( 3404 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 3405 outSRV->setLabels("TexStorage2DArray.SRV", &mKHRDebugLabel); 3406 3407 return angle::Result::Continue; 3408 } 3409 3410 angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context, 3411 int level, 3412 DXGI_FORMAT format, 3413 const TextureHelper11 &texture, 3414 d3d11::SharedSRV *outSRV) 3415 { 3416 ASSERT(outSRV); 3417 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3418 srvDesc.Format = format; 3419 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 3420 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; 3421 srvDesc.Texture2DArray.MipLevels = 1; 3422 srvDesc.Texture2DArray.FirstArraySlice = 0; 3423 srvDesc.Texture2DArray.ArraySize = mTextureDepth; 3424 ANGLE_TRY( 3425 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 3426 outSRV->setLabels("TexStorage2DArray.SRVForImage", &mKHRDebugLabel); 3427 return angle::Result::Continue; 3428 } 3429 3430 angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context, 3431 int level, 3432 DXGI_FORMAT format, 3433 const TextureHelper11 &texture, 3434 d3d11::SharedUAV *outUAV) 3435 { 3436 ASSERT(outUAV); 3437 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; 3438 uavDesc.Format = format; 3439 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; 3440 uavDesc.Texture2DArray.MipSlice = mTopLevel + level; 3441 uavDesc.Texture2DArray.FirstArraySlice = 0; 3442 uavDesc.Texture2DArray.ArraySize = mTextureDepth; 3443 ANGLE_TRY( 3444 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV)); 3445 outUAV->setLabels("TexStorage2DArray.UAVForImage", &mKHRDebugLabel); 3446 return angle::Result::Continue; 3447 } 3448 3449 angle::Result TextureStorage11_2DArray::findRenderTarget(const gl::Context *context, 3450 const gl::ImageIndex &index, 3451 GLsizei samples, 3452 RenderTargetD3D **outRT) const 3453 { 3454 ASSERT(index.hasLayer()); 3455 3456 const int mipLevel = index.getLevelIndex(); 3457 const int layer = index.getLayerIndex(); 3458 const int numLayers = index.getLayerCount(); 3459 3460 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3461 3462 LevelLayerRangeKey key(mipLevel, layer, numLayers); 3463 if (mRenderTargets.find(key) == mRenderTargets.end()) 3464 { 3465 ASSERT(outRT); 3466 *outRT = nullptr; 3467 return angle::Result::Continue; 3468 } 3469 3470 ASSERT(outRT); 3471 *outRT = mRenderTargets.at(key).get(); 3472 return angle::Result::Continue; 3473 } 3474 3475 angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context, 3476 const TextureHelper11 &texture, 3477 const gl::ImageIndex &index, 3478 DXGI_FORMAT resourceFormat, 3479 d3d11::SharedSRV *srv) const 3480 { 3481 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3482 srvDesc.Format = resourceFormat; 3483 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 3484 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex(); 3485 srvDesc.Texture2DArray.MipLevels = 1; 3486 srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex(); 3487 srvDesc.Texture2DArray.ArraySize = index.getLayerCount(); 3488 3489 ANGLE_TRY( 3490 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv)); 3491 3492 return angle::Result::Continue; 3493 } 3494 3495 angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context, 3496 const gl::ImageIndex &index, 3497 GLsizei samples, 3498 RenderTargetD3D **outRT) 3499 { 3500 ASSERT(index.hasLayer()); 3501 3502 const int mipLevel = index.getLevelIndex(); 3503 const int layer = index.getLayerIndex(); 3504 const int numLayers = index.getLayerCount(); 3505 3506 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3507 3508 LevelLayerRangeKey key(mipLevel, layer, numLayers); 3509 if (mRenderTargets.find(key) == mRenderTargets.end()) 3510 { 3511 const TextureHelper11 *texture = nullptr; 3512 ANGLE_TRY(getResource(context, &texture)); 3513 d3d11::SharedSRV srv; 3514 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); 3515 d3d11::SharedSRV blitSRV; 3516 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) 3517 { 3518 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, 3519 &blitSRV)); 3520 } 3521 else 3522 { 3523 blitSRV = srv.makeCopy(); 3524 } 3525 3526 srv.setLabels("TexStorage2DArray.RenderTargetSRV", &mKHRDebugLabel); 3527 3528 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 3529 { 3530 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3531 rtvDesc.Format = mFormatInfo.rtvFormat; 3532 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 3533 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; 3534 rtvDesc.Texture2DArray.FirstArraySlice = layer; 3535 rtvDesc.Texture2DArray.ArraySize = numLayers; 3536 3537 d3d11::RenderTargetView rtv; 3538 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 3539 texture->get(), &rtv)); 3540 rtv.setLabels("TexStorage2DArray.RenderTargetRTV", &mKHRDebugLabel); 3541 3542 mRenderTargets[key].reset(new TextureRenderTarget11( 3543 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), 3544 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); 3545 } 3546 else 3547 { 3548 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); 3549 3550 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 3551 dsvDesc.Format = mFormatInfo.dsvFormat; 3552 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; 3553 dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; 3554 dsvDesc.Texture2DArray.FirstArraySlice = layer; 3555 dsvDesc.Texture2DArray.ArraySize = numLayers; 3556 dsvDesc.Flags = 0; 3557 3558 d3d11::DepthStencilView dsv; 3559 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc, 3560 texture->get(), &dsv)); 3561 dsv.setLabels("TexStorage2DArray.RenderTargetDSV", &mKHRDebugLabel); 3562 3563 mRenderTargets[key].reset(new TextureRenderTarget11( 3564 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), 3565 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); 3566 } 3567 } 3568 3569 ASSERT(outRT); 3570 *outRT = mRenderTargets[key].get(); 3571 return angle::Result::Continue; 3572 } 3573 3574 angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context, 3575 const TextureHelper11 **outTexture) 3576 { 3577 if (!mSwizzleTexture.valid()) 3578 { 3579 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); 3580 3581 D3D11_TEXTURE2D_DESC desc; 3582 desc.Width = mTextureWidth; 3583 desc.Height = mTextureHeight; 3584 desc.MipLevels = mMipLevels; 3585 desc.ArraySize = mTextureDepth; 3586 desc.Format = format.texFormat; 3587 desc.SampleDesc.Count = 1; 3588 desc.SampleDesc.Quality = 0; 3589 desc.Usage = D3D11_USAGE_DEFAULT; 3590 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; 3591 desc.CPUAccessFlags = 0; 3592 desc.MiscFlags = 0; 3593 3594 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format, 3595 &mSwizzleTexture)); 3596 mSwizzleTexture.setLabels("TexStorage2DArray.SwizzleTexture", &mKHRDebugLabel); 3597 } 3598 3599 *outTexture = &mSwizzleTexture; 3600 return angle::Result::Continue; 3601 } 3602 3603 angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget( 3604 const gl::Context *context, 3605 int mipLevel, 3606 const d3d11::RenderTargetView **outRTV) 3607 { 3608 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 3609 ASSERT(outRTV); 3610 3611 if (!mSwizzleRenderTargets[mipLevel].valid()) 3612 { 3613 const TextureHelper11 *swizzleTexture = nullptr; 3614 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture)); 3615 3616 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3617 rtvDesc.Format = 3618 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; 3619 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 3620 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; 3621 rtvDesc.Texture2DArray.FirstArraySlice = 0; 3622 rtvDesc.Texture2DArray.ArraySize = mTextureDepth; 3623 3624 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 3625 mSwizzleTexture.get(), 3626 &mSwizzleRenderTargets[mipLevel])); 3627 } 3628 3629 *outRTV = &mSwizzleRenderTargets[mipLevel]; 3630 return angle::Result::Continue; 3631 } 3632 3633 angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context, 3634 DropStencil *dropStencilOut) 3635 { 3636 if (mDropStencilTexture.valid()) 3637 { 3638 *dropStencilOut = DropStencil::ALREADY_EXISTS; 3639 return angle::Result::Continue; 3640 } 3641 3642 D3D11_TEXTURE2D_DESC dropDesc = {}; 3643 dropDesc.ArraySize = mTextureDepth; 3644 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; 3645 dropDesc.CPUAccessFlags = 0; 3646 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; 3647 dropDesc.Height = mTextureHeight; 3648 dropDesc.MipLevels = mMipLevels; 3649 dropDesc.MiscFlags = 0; 3650 dropDesc.SampleDesc.Count = 1; 3651 dropDesc.SampleDesc.Quality = 0; 3652 dropDesc.Usage = D3D11_USAGE_DEFAULT; 3653 dropDesc.Width = mTextureWidth; 3654 3655 const auto &format = 3656 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); 3657 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format, 3658 &mDropStencilTexture)); 3659 mDropStencilTexture.setLabels("TexStorage2DArray.DropStencil", &mKHRDebugLabel); 3660 3661 std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth); 3662 3663 ANGLE_TRY(initDropStencilTexture( 3664 context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data()))); 3665 3666 *dropStencilOut = DropStencil::CREATED; 3667 return angle::Result::Continue; 3668 } 3669 3670 void TextureStorage11_2DArray::onLabelUpdate() 3671 { 3672 if (mTexture.valid()) 3673 { 3674 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 3675 } 3676 if (mSwizzleTexture.valid()) 3677 { 3678 mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel); 3679 } 3680 } 3681 3682 TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer, 3683 GLenum internalformat, 3684 GLsizei width, 3685 GLsizei height, 3686 int levels, 3687 int samples, 3688 bool fixedSampleLocations, 3689 const std::string &label) 3690 : TextureStorage11ImmutableBase(renderer, 3691 GetTextureBindFlags(internalformat, 3692 renderer->getRenderer11DeviceCaps(), 3693 BindFlags::RenderTarget()), 3694 GetTextureMiscFlags(internalformat, 3695 renderer->getRenderer11DeviceCaps(), 3696 BindFlags::RenderTarget(), 3697 levels), 3698 internalformat, 3699 label), 3700 mTexture(), 3701 mRenderTarget(nullptr) 3702 { 3703 // There are no multisampled compressed formats, so there's no need to adjust texture size 3704 // according to block size. 3705 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1); 3706 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1); 3707 3708 mMipLevels = 1; 3709 mTextureWidth = width; 3710 mTextureHeight = height; 3711 mTextureDepth = 1; 3712 mSamples = samples; 3713 mFixedSampleLocations = fixedSampleLocations; 3714 } 3715 3716 angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context) 3717 { 3718 mRenderTarget.reset(); 3719 return angle::Result::Continue; 3720 } 3721 3722 TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {} 3723 3724 angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context, 3725 TextureStorage *destStorage) 3726 { 3727 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 3728 return angle::Result::Stop; 3729 } 3730 3731 angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context, 3732 const TextureHelper11 **outResource) 3733 { 3734 ANGLE_TRY(ensureTextureExists(context, 1)); 3735 3736 *outResource = &mTexture; 3737 return angle::Result::Continue; 3738 } 3739 3740 angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context, 3741 int mipLevels) 3742 { 3743 // For Multisampled textures, mipLevels always equals 1. 3744 ASSERT(mipLevels == 1); 3745 3746 // if the width or height is not positive this should be treated as an incomplete texture 3747 // we handle that here by skipping the d3d texture creation 3748 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0) 3749 { 3750 D3D11_TEXTURE2D_DESC desc; 3751 ZeroMemory(&desc, sizeof(desc)); 3752 desc.Width = mTextureWidth; // Compressed texture size constraints? 3753 desc.Height = mTextureHeight; 3754 desc.MipLevels = mipLevels; 3755 desc.ArraySize = 1; 3756 desc.Format = mFormatInfo.texFormat; 3757 desc.Usage = D3D11_USAGE_DEFAULT; 3758 desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS; 3759 desc.CPUAccessFlags = 0; 3760 desc.MiscFlags = getMiscFlags(); 3761 3762 const gl::TextureCaps &textureCaps = 3763 mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat); 3764 GLuint supportedSamples = textureCaps.getNearestSamples(mSamples); 3765 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; 3766 desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples); 3767 3768 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 3769 &mTexture)); 3770 mTexture.setLabels("TexStorage2DMS.Texture", &mKHRDebugLabel); 3771 } 3772 3773 return angle::Result::Continue; 3774 } 3775 3776 angle::Result TextureStorage11_2DMultisample::findRenderTarget(const gl::Context *context, 3777 const gl::ImageIndex &index, 3778 GLsizei samples, 3779 RenderTargetD3D **outRT) const 3780 { 3781 ASSERT(!index.hasLayer()); 3782 3783 const int level = index.getLevelIndex(); 3784 ASSERT(level == 0); 3785 3786 ASSERT(outRT); 3787 *outRT = mRenderTarget.get(); 3788 return angle::Result::Continue; 3789 } 3790 3791 angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context, 3792 const gl::ImageIndex &index, 3793 GLsizei samples, 3794 RenderTargetD3D **outRT) 3795 { 3796 ASSERT(!index.hasLayer()); 3797 3798 const int level = index.getLevelIndex(); 3799 ASSERT(level == 0); 3800 3801 ASSERT(outRT); 3802 if (mRenderTarget) 3803 { 3804 *outRT = mRenderTarget.get(); 3805 return angle::Result::Continue; 3806 } 3807 3808 const TextureHelper11 *texture = nullptr; 3809 ANGLE_TRY(getResource(context, &texture)); 3810 3811 const d3d11::SharedSRV *srv = nullptr; 3812 ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv)); 3813 3814 const d3d11::SharedSRV *blitSRV = nullptr; 3815 ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV)); 3816 3817 Context11 *context11 = GetImplAs<Context11>(context); 3818 3819 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 3820 { 3821 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 3822 rtvDesc.Format = mFormatInfo.rtvFormat; 3823 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; 3824 3825 d3d11::RenderTargetView rtv; 3826 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv)); 3827 3828 mRenderTarget.reset(new TextureRenderTarget11( 3829 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), 3830 getLevelWidth(level), getLevelHeight(level), 1, mSamples)); 3831 3832 *outRT = mRenderTarget.get(); 3833 return angle::Result::Continue; 3834 } 3835 3836 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); 3837 3838 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 3839 dsvDesc.Format = mFormatInfo.dsvFormat; 3840 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; 3841 dsvDesc.Flags = 0; 3842 3843 d3d11::DepthStencilView dsv; 3844 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv)); 3845 3846 mRenderTarget.reset(new TextureRenderTarget11( 3847 std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), 3848 getLevelWidth(level), getLevelHeight(level), 1, mSamples)); 3849 3850 *outRT = mRenderTarget.get(); 3851 return angle::Result::Continue; 3852 } 3853 3854 angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context, 3855 int baseLevel, 3856 int mipLevels, 3857 DXGI_FORMAT format, 3858 const TextureHelper11 &texture, 3859 d3d11::SharedSRV *outSRV) 3860 { 3861 ASSERT(outSRV); 3862 3863 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 3864 srvDesc.Format = format; 3865 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; 3866 3867 ANGLE_TRY( 3868 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 3869 outSRV->setLabels("TexStorage2DMS.SRV", &mKHRDebugLabel); 3870 return angle::Result::Continue; 3871 } 3872 3873 angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context, 3874 const TextureHelper11 **outTexture) 3875 { 3876 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 3877 return angle::Result::Stop; 3878 } 3879 3880 angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget( 3881 const gl::Context *context, 3882 int mipLevel, 3883 const d3d11::RenderTargetView **outRTV) 3884 { 3885 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 3886 return angle::Result::Stop; 3887 } 3888 3889 angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context, 3890 DropStencil *dropStencilOut) 3891 { 3892 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 3893 return angle::Result::Stop; 3894 } 3895 3896 void TextureStorage11_2DMultisample::onLabelUpdate() 3897 { 3898 if (mTexture.valid()) 3899 { 3900 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 3901 } 3902 } 3903 3904 TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer, 3905 GLenum internalformat, 3906 GLsizei width, 3907 GLsizei height, 3908 GLsizei depth, 3909 int levels, 3910 int samples, 3911 bool fixedSampleLocations, 3912 const std::string &label) 3913 : TextureStorage11ImmutableBase(renderer, 3914 GetTextureBindFlags(internalformat, 3915 renderer->getRenderer11DeviceCaps(), 3916 BindFlags::RenderTarget()), 3917 GetTextureMiscFlags(internalformat, 3918 renderer->getRenderer11DeviceCaps(), 3919 BindFlags::RenderTarget(), 3920 levels), 3921 internalformat, 3922 label), 3923 mTexture() 3924 { 3925 // There are no multisampled compressed formats, so there's no need to adjust texture size 3926 // according to block size. 3927 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1); 3928 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1); 3929 3930 mMipLevels = 1; 3931 mTextureWidth = width; 3932 mTextureHeight = height; 3933 mTextureDepth = depth; 3934 mSamples = samples; 3935 mFixedSampleLocations = fixedSampleLocations; 3936 } 3937 3938 angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context) 3939 { 3940 return angle::Result::Continue; 3941 } 3942 3943 TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {} 3944 3945 angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context, 3946 TextureStorage *destStorage) 3947 { 3948 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 3949 return angle::Result::Stop; 3950 } 3951 3952 angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context, 3953 const TextureHelper11 **outResource) 3954 { 3955 ANGLE_TRY(ensureTextureExists(context, 1)); 3956 3957 *outResource = &mTexture; 3958 return angle::Result::Continue; 3959 } 3960 3961 angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context, 3962 int mipLevels) 3963 { 3964 // For multisampled textures, mipLevels always equals 1. 3965 ASSERT(mipLevels == 1); 3966 3967 // if the width or height is not positive this should be treated as an incomplete texture 3968 // we handle that here by skipping the d3d texture creation 3969 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0) 3970 { 3971 D3D11_TEXTURE2D_DESC desc; 3972 ZeroMemory(&desc, sizeof(desc)); 3973 desc.Width = mTextureWidth; 3974 desc.Height = mTextureHeight; 3975 desc.MipLevels = mipLevels; 3976 desc.ArraySize = mTextureDepth; 3977 desc.Format = mFormatInfo.texFormat; 3978 desc.Usage = D3D11_USAGE_DEFAULT; 3979 desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS; 3980 desc.CPUAccessFlags = 0; 3981 desc.MiscFlags = getMiscFlags(); 3982 3983 const gl::TextureCaps &textureCaps = 3984 mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat); 3985 GLuint supportedSamples = textureCaps.getNearestSamples(mSamples); 3986 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; 3987 desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples); 3988 3989 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo, 3990 &mTexture)); 3991 mTexture.setLabels("TexStorage2DMSArray.Texture", &mKHRDebugLabel); 3992 } 3993 3994 return angle::Result::Continue; 3995 } 3996 3997 angle::Result TextureStorage11_2DMultisampleArray::findRenderTarget(const gl::Context *context, 3998 const gl::ImageIndex &index, 3999 GLsizei samples, 4000 RenderTargetD3D **outRT) const 4001 { 4002 ASSERT(index.hasLayer()); 4003 4004 const int mipLevel = index.getLevelIndex(); 4005 ASSERT(mipLevel == 0); 4006 const int layer = index.getLayerIndex(); 4007 const int numLayers = index.getLayerCount(); 4008 4009 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 4010 4011 TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers); 4012 if (mRenderTargets.find(key) == mRenderTargets.end()) 4013 { 4014 ASSERT(outRT); 4015 *outRT = nullptr; 4016 return angle::Result::Continue; 4017 } 4018 4019 ASSERT(outRT); 4020 *outRT = mRenderTargets.at(key).get(); 4021 return angle::Result::Continue; 4022 } 4023 4024 angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV( 4025 const gl::Context *context, 4026 const TextureHelper11 &texture, 4027 const gl::ImageIndex &index, 4028 DXGI_FORMAT resourceFormat, 4029 d3d11::SharedSRV *srv) const 4030 { 4031 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 4032 srvDesc.Format = resourceFormat; 4033 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; 4034 srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex(); 4035 srvDesc.Texture2DMSArray.ArraySize = index.getLayerCount(); 4036 4037 ANGLE_TRY( 4038 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv)); 4039 4040 return angle::Result::Continue; 4041 } 4042 4043 angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context, 4044 const gl::ImageIndex &index, 4045 GLsizei samples, 4046 RenderTargetD3D **outRT) 4047 { 4048 ASSERT(index.hasLayer()); 4049 4050 const int mipLevel = index.getLevelIndex(); 4051 ASSERT(mipLevel == 0); 4052 const int layer = index.getLayerIndex(); 4053 const int numLayers = index.getLayerCount(); 4054 4055 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); 4056 4057 TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers); 4058 if (mRenderTargets.find(key) == mRenderTargets.end()) 4059 { 4060 const TextureHelper11 *texture = nullptr; 4061 ANGLE_TRY(getResource(context, &texture)); 4062 d3d11::SharedSRV srv; 4063 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv)); 4064 d3d11::SharedSRV blitSRV; 4065 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) 4066 { 4067 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat, 4068 &blitSRV)); 4069 } 4070 else 4071 { 4072 blitSRV = srv.makeCopy(); 4073 } 4074 4075 srv.setLabels("TexStorage2DMSArray.RenderTargetSRV", &mKHRDebugLabel); 4076 4077 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 4078 { 4079 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 4080 rtvDesc.Format = mFormatInfo.rtvFormat; 4081 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; 4082 rtvDesc.Texture2DMSArray.FirstArraySlice = layer; 4083 rtvDesc.Texture2DMSArray.ArraySize = numLayers; 4084 4085 d3d11::RenderTargetView rtv; 4086 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc, 4087 texture->get(), &rtv)); 4088 rtv.setLabels("TexStorage2DMSArray.RenderTargetRTV", &mKHRDebugLabel); 4089 4090 mRenderTargets[key].reset(new TextureRenderTarget11( 4091 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), 4092 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples)); 4093 } 4094 else 4095 { 4096 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); 4097 4098 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 4099 dsvDesc.Format = mFormatInfo.dsvFormat; 4100 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; 4101 dsvDesc.Texture2DMSArray.FirstArraySlice = layer; 4102 dsvDesc.Texture2DMSArray.ArraySize = numLayers; 4103 dsvDesc.Flags = 0; 4104 4105 d3d11::DepthStencilView dsv; 4106 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc, 4107 texture->get(), &dsv)); 4108 dsv.setLabels("TexStorage2DMSArray.RenderTargetDSV", &mKHRDebugLabel); 4109 4110 mRenderTargets[key].reset(new TextureRenderTarget11( 4111 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), 4112 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples)); 4113 } 4114 } 4115 4116 ASSERT(outRT); 4117 *outRT = mRenderTargets[key].get(); 4118 return angle::Result::Continue; 4119 } 4120 4121 angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler( 4122 const gl::Context *context, 4123 int baseLevel, 4124 int mipLevels, 4125 DXGI_FORMAT format, 4126 const TextureHelper11 &texture, 4127 d3d11::SharedSRV *outSRV) 4128 { 4129 ASSERT(outSRV); 4130 4131 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 4132 srvDesc.Format = format; 4133 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; 4134 srvDesc.Texture2DMSArray.FirstArraySlice = 0; 4135 srvDesc.Texture2DMSArray.ArraySize = mTextureDepth; 4136 4137 ANGLE_TRY( 4138 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 4139 outSRV->setLabels("TexStorage2DMSArray.SRV", &mKHRDebugLabel); 4140 return angle::Result::Continue; 4141 } 4142 4143 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture( 4144 const gl::Context *context, 4145 const TextureHelper11 **outTexture) 4146 { 4147 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4148 return angle::Result::Stop; 4149 } 4150 4151 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget( 4152 const gl::Context *context, 4153 int mipLevel, 4154 const d3d11::RenderTargetView **outRTV) 4155 { 4156 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4157 return angle::Result::Stop; 4158 } 4159 4160 angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture( 4161 const gl::Context *context, 4162 DropStencil *dropStencilOut) 4163 { 4164 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4165 return angle::Result::Stop; 4166 } 4167 4168 void TextureStorage11_2DMultisampleArray::onLabelUpdate() 4169 { 4170 if (mTexture.valid()) 4171 { 4172 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 4173 } 4174 } 4175 4176 TextureStorage11_Buffer::TextureStorage11_Buffer(Renderer11 *renderer, 4177 const gl::OffsetBindingPointer<gl::Buffer> &buffer, 4178 GLenum internalFormat, 4179 const std::string &label) 4180 : TextureStorage11(renderer, 4181 D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, 4182 0, 4183 internalFormat, 4184 label), 4185 mTexture(), 4186 mBuffer(buffer), 4187 mDataSize(GetBoundBufferAvailableSize(buffer)) 4188 { 4189 unsigned int bytesPerPixel = 4190 static_cast<unsigned int>(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.srvFormat).pixelBytes); 4191 mMipLevels = 1; 4192 mTextureWidth = static_cast<unsigned int>(mDataSize / bytesPerPixel); 4193 mTextureHeight = 1; 4194 mTextureDepth = 1; 4195 } 4196 4197 TextureStorage11_Buffer::~TextureStorage11_Buffer() {} 4198 4199 angle::Result TextureStorage11_Buffer::initTexture(const gl::Context *context) 4200 { 4201 if (!mTexture.valid()) 4202 { 4203 ID3D11Buffer *buffer = nullptr; 4204 Buffer11 *buffer11 = GetImplAs<Buffer11>(mBuffer.get()); 4205 ANGLE_TRY(buffer11->getBuffer(context, rx::BufferUsage::BUFFER_USAGE_TYPED_UAV, &buffer)); 4206 mTexture.set(buffer, mFormatInfo); 4207 mTexture.get()->AddRef(); 4208 } 4209 return angle::Result::Continue; 4210 } 4211 4212 angle::Result TextureStorage11_Buffer::getResource(const gl::Context *context, 4213 const TextureHelper11 **outResource) 4214 { 4215 ANGLE_TRY(initTexture(context)); 4216 *outResource = &mTexture; 4217 return angle::Result::Continue; 4218 } 4219 4220 angle::Result TextureStorage11_Buffer::getMippedResource(const gl::Context *context, 4221 const TextureHelper11 **) 4222 { 4223 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4224 return angle::Result::Stop; 4225 } 4226 4227 angle::Result TextureStorage11_Buffer::findRenderTarget(const gl::Context *context, 4228 const gl::ImageIndex &index, 4229 GLsizei samples, 4230 RenderTargetD3D **outRT) const 4231 { 4232 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4233 return angle::Result::Stop; 4234 } 4235 4236 angle::Result TextureStorage11_Buffer::getRenderTarget(const gl::Context *context, 4237 const gl::ImageIndex &index, 4238 GLsizei samples, 4239 RenderTargetD3D **outRT) 4240 { 4241 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4242 return angle::Result::Stop; 4243 } 4244 4245 angle::Result TextureStorage11_Buffer::getSwizzleTexture(const gl::Context *context, 4246 const TextureHelper11 **outTexture) 4247 { 4248 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4249 return angle::Result::Stop; 4250 } 4251 4252 angle::Result TextureStorage11_Buffer::getSwizzleRenderTarget( 4253 const gl::Context *context, 4254 int mipLevel, 4255 const d3d11::RenderTargetView **outRTV) 4256 { 4257 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context)); 4258 return angle::Result::Stop; 4259 } 4260 4261 angle::Result TextureStorage11_Buffer::createSRVForSampler(const gl::Context *context, 4262 int baseLevel, 4263 int mipLevels, 4264 DXGI_FORMAT format, 4265 const TextureHelper11 &texture, 4266 d3d11::SharedSRV *outSRV) 4267 { 4268 ASSERT(baseLevel == 0); 4269 ASSERT(mipLevels == 1); 4270 ASSERT(outSRV); 4271 ANGLE_TRY(initTexture(context)); 4272 UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes); 4273 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 4274 srvDesc.Format = format; 4275 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; 4276 ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); 4277 srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel); 4278 srvDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel); 4279 4280 ANGLE_TRY( 4281 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 4282 outSRV->setLabels("TexBuffer.SRV", &mKHRDebugLabel); 4283 4284 return angle::Result::Continue; 4285 } 4286 4287 angle::Result TextureStorage11_Buffer::createSRVForImage(const gl::Context *context, 4288 int level, 4289 DXGI_FORMAT format, 4290 const TextureHelper11 &texture, 4291 d3d11::SharedSRV *outSRV) 4292 { 4293 ANGLE_TRY(initTexture(context)); 4294 UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes); 4295 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 4296 srvDesc.Format = format; 4297 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; 4298 ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); 4299 srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel); 4300 srvDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel); 4301 4302 ANGLE_TRY( 4303 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV)); 4304 outSRV->setLabels("TexBuffer.SRVForImage", &mKHRDebugLabel); 4305 4306 return angle::Result::Continue; 4307 } 4308 angle::Result TextureStorage11_Buffer::createUAVForImage(const gl::Context *context, 4309 int level, 4310 DXGI_FORMAT format, 4311 const TextureHelper11 &texture, 4312 d3d11::SharedUAV *outUAV) 4313 { 4314 ANGLE_TRY(initTexture(context)); 4315 unsigned bytesPerPixel = d3d11::GetDXGIFormatSizeInfo(format).pixelBytes; 4316 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; 4317 uavDesc.Format = format; 4318 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; 4319 ASSERT(mBuffer.getOffset() % bytesPerPixel == 0); 4320 uavDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel); 4321 uavDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel); 4322 uavDesc.Buffer.Flags = 0; 4323 4324 ANGLE_TRY( 4325 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV)); 4326 outUAV->setLabels("TexBuffer.UAVForImage", &mKHRDebugLabel); 4327 4328 return angle::Result::Continue; 4329 } 4330 4331 void TextureStorage11_Buffer::associateImage(Image11 *image, const gl::ImageIndex &index) {} 4332 void TextureStorage11_Buffer::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) 4333 {} 4334 void TextureStorage11_Buffer::verifyAssociatedImageValid(const gl::ImageIndex &index, 4335 Image11 *expectedImage) 4336 {} 4337 angle::Result TextureStorage11_Buffer::releaseAssociatedImage(const gl::Context *context, 4338 const gl::ImageIndex &index, 4339 Image11 *incomingImage) 4340 { 4341 return angle::Result::Continue; 4342 } 4343 4344 void TextureStorage11_Buffer::onLabelUpdate() 4345 { 4346 if (mTexture.valid()) 4347 { 4348 mTexture.setKHRDebugLabel(&mKHRDebugLabel); 4349 } 4350 } 4351 4352 } // namespace rx