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