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