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