1 //
2 // Copyright 2017 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 // ResourceManager11:
7 //   Centralized point of allocation for all D3D11 Resources.
8 
9 #include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
13 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
14 
15 namespace rx
16 {
17 
18 namespace
19 {
20 
21 constexpr uint8_t kDebugInitTextureDataValue = 0x48;
22 constexpr FLOAT kDebugColorInitClearValue[4] = {0.3f, 0.5f, 0.7f, 0.5f};
23 constexpr FLOAT kDebugDepthInitValue         = 0.2f;
24 constexpr UINT8 kDebugStencilInitValue       = 3;
25 
26 // A hard limit on buffer size. This works around a problem in the NVIDIA drivers where buffer sizes
27 // close to MAX_UINT would give undefined results. The limit of MAX_UINT/2 should be generous enough
28 // for almost any demanding application.
29 constexpr UINT kMaximumBufferSizeHardLimit = std::numeric_limits<UINT>::max() >> 1;
30 
ComputeMippedMemoryUsage(unsigned int width,unsigned int height,unsigned int depth,uint64_t pixelSize,unsigned int mipLevels)31 uint64_t ComputeMippedMemoryUsage(unsigned int width,
32                                   unsigned int height,
33                                   unsigned int depth,
34                                   uint64_t pixelSize,
35                                   unsigned int mipLevels)
36 {
37     uint64_t sizeSum = 0;
38 
39     for (unsigned int level = 0; level < mipLevels; ++level)
40     {
41         unsigned int mipWidth  = std::max(width >> level, 1u);
42         unsigned int mipHeight = std::max(height >> level, 1u);
43         unsigned int mipDepth  = std::max(depth >> level, 1u);
44         sizeSum += static_cast<uint64_t>(mipWidth * mipHeight * mipDepth) * pixelSize;
45     }
46 
47     return sizeSum;
48 }
49 
ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC * desc)50 uint64_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc)
51 {
52     ASSERT(desc);
53     uint64_t pixelBytes =
54         static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
55     return ComputeMippedMemoryUsage(desc->Width, desc->Height, 1, pixelBytes, desc->MipLevels);
56 }
57 
ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC * desc)58 uint64_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc)
59 {
60     ASSERT(desc);
61     uint64_t pixelBytes =
62         static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
63     return ComputeMippedMemoryUsage(desc->Width, desc->Height, desc->Depth, pixelBytes,
64                                     desc->MipLevels);
65 }
66 
ComputeMemoryUsage(const D3D11_BUFFER_DESC * desc)67 uint64_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc)
68 {
69     ASSERT(desc);
70     return static_cast<uint64_t>(desc->ByteWidth);
71 }
72 
73 template <typename T>
ComputeMemoryUsage(const T * desc)74 uint64_t ComputeMemoryUsage(const T *desc)
75 {
76     return 0;
77 }
78 
79 template <ResourceType ResourceT>
ComputeGenericMemoryUsage(ID3D11DeviceChild * genericResource)80 uint64_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource)
81 {
82     auto *typedResource = static_cast<GetD3D11Type<ResourceT> *>(genericResource);
83     GetDescType<ResourceT> desc;
84     typedResource->GetDesc(&desc);
85     return ComputeMemoryUsage(&desc);
86 }
87 
ComputeGenericMemoryUsage(ResourceType resourceType,ID3D11DeviceChild * resource)88 uint64_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource)
89 {
90     switch (resourceType)
91     {
92         case ResourceType::Texture2D:
93             return ComputeGenericMemoryUsage<ResourceType::Texture2D>(resource);
94         case ResourceType::Texture3D:
95             return ComputeGenericMemoryUsage<ResourceType::Texture3D>(resource);
96         case ResourceType::Buffer:
97             return ComputeGenericMemoryUsage<ResourceType::Buffer>(resource);
98 
99         default:
100             return 0;
101     }
102 }
103 
CreateResource(ID3D11Device * device,const D3D11_BLEND_DESC * desc,void *,ID3D11BlendState ** blendState)104 HRESULT CreateResource(ID3D11Device *device,
105                        const D3D11_BLEND_DESC *desc,
106                        void * /*initData*/,
107                        ID3D11BlendState **blendState)
108 {
109     return device->CreateBlendState(desc, blendState);
110 }
111 
CreateResource(ID3D11Device * device,const D3D11_BUFFER_DESC * desc,const D3D11_SUBRESOURCE_DATA * initData,ID3D11Buffer ** buffer)112 HRESULT CreateResource(ID3D11Device *device,
113                        const D3D11_BUFFER_DESC *desc,
114                        const D3D11_SUBRESOURCE_DATA *initData,
115                        ID3D11Buffer **buffer)
116 {
117     // Force buffers to be limited to a fixed max size.
118     if (desc->ByteWidth > kMaximumBufferSizeHardLimit)
119     {
120         return E_OUTOFMEMORY;
121     }
122 
123     return device->CreateBuffer(desc, initData, buffer);
124 }
125 
CreateResource(ID3D11Device * device,const ShaderData * desc,void *,ID3D11ComputeShader ** resourceOut)126 HRESULT CreateResource(ID3D11Device *device,
127                        const ShaderData *desc,
128                        void * /*initData*/,
129                        ID3D11ComputeShader **resourceOut)
130 {
131     return device->CreateComputeShader(desc->get(), desc->size(), nullptr, resourceOut);
132 }
133 
CreateResource(ID3D11Device * device,const D3D11_DEPTH_STENCIL_DESC * desc,void *,ID3D11DepthStencilState ** resourceOut)134 HRESULT CreateResource(ID3D11Device *device,
135                        const D3D11_DEPTH_STENCIL_DESC *desc,
136                        void * /*initData*/,
137                        ID3D11DepthStencilState **resourceOut)
138 {
139     return device->CreateDepthStencilState(desc, resourceOut);
140 }
141 
CreateResource(ID3D11Device * device,const D3D11_DEPTH_STENCIL_VIEW_DESC * desc,ID3D11Resource * resource,ID3D11DepthStencilView ** resourceOut)142 HRESULT CreateResource(ID3D11Device *device,
143                        const D3D11_DEPTH_STENCIL_VIEW_DESC *desc,
144                        ID3D11Resource *resource,
145                        ID3D11DepthStencilView **resourceOut)
146 {
147     return device->CreateDepthStencilView(resource, desc, resourceOut);
148 }
149 
CreateResource(ID3D11Device * device,const ShaderData * desc,const std::vector<D3D11_SO_DECLARATION_ENTRY> * initData,ID3D11GeometryShader ** resourceOut)150 HRESULT CreateResource(ID3D11Device *device,
151                        const ShaderData *desc,
152                        const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
153                        ID3D11GeometryShader **resourceOut)
154 {
155     if (initData)
156     {
157         return device->CreateGeometryShaderWithStreamOutput(
158             desc->get(), desc->size(), initData->data(), static_cast<UINT>(initData->size()),
159             nullptr, 0, 0, nullptr, resourceOut);
160     }
161     else
162     {
163         return device->CreateGeometryShader(desc->get(), desc->size(), nullptr, resourceOut);
164     }
165 }
166 
CreateResource(ID3D11Device * device,const InputElementArray * desc,const ShaderData * initData,ID3D11InputLayout ** resourceOut)167 HRESULT CreateResource(ID3D11Device *device,
168                        const InputElementArray *desc,
169                        const ShaderData *initData,
170                        ID3D11InputLayout **resourceOut)
171 {
172     return device->CreateInputLayout(desc->get(), static_cast<UINT>(desc->size()), initData->get(),
173                                      initData->size(), resourceOut);
174 }
175 
CreateResource(ID3D11Device * device,const ShaderData * desc,void *,ID3D11PixelShader ** resourceOut)176 HRESULT CreateResource(ID3D11Device *device,
177                        const ShaderData *desc,
178                        void * /*initData*/,
179                        ID3D11PixelShader **resourceOut)
180 {
181     return device->CreatePixelShader(desc->get(), desc->size(), nullptr, resourceOut);
182 }
183 
CreateResource(ID3D11Device * device,const D3D11_QUERY_DESC * desc,void *,ID3D11Query ** resourceOut)184 HRESULT CreateResource(ID3D11Device *device,
185                        const D3D11_QUERY_DESC *desc,
186                        void * /*initData*/,
187                        ID3D11Query **resourceOut)
188 {
189     return device->CreateQuery(desc, resourceOut);
190 }
191 
CreateResource(ID3D11Device * device,const D3D11_RASTERIZER_DESC * desc,void *,ID3D11RasterizerState ** rasterizerState)192 HRESULT CreateResource(ID3D11Device *device,
193                        const D3D11_RASTERIZER_DESC *desc,
194                        void * /*initData*/,
195                        ID3D11RasterizerState **rasterizerState)
196 {
197     return device->CreateRasterizerState(desc, rasterizerState);
198 }
199 
CreateResource(ID3D11Device * device,const D3D11_RENDER_TARGET_VIEW_DESC * desc,ID3D11Resource * resource,ID3D11RenderTargetView ** renderTargetView)200 HRESULT CreateResource(ID3D11Device *device,
201                        const D3D11_RENDER_TARGET_VIEW_DESC *desc,
202                        ID3D11Resource *resource,
203                        ID3D11RenderTargetView **renderTargetView)
204 {
205     return device->CreateRenderTargetView(resource, desc, renderTargetView);
206 }
207 
CreateResource(ID3D11Device * device,const D3D11_SAMPLER_DESC * desc,void *,ID3D11SamplerState ** resourceOut)208 HRESULT CreateResource(ID3D11Device *device,
209                        const D3D11_SAMPLER_DESC *desc,
210                        void * /*initData*/,
211                        ID3D11SamplerState **resourceOut)
212 {
213     return device->CreateSamplerState(desc, resourceOut);
214 }
215 
CreateResource(ID3D11Device * device,const D3D11_SHADER_RESOURCE_VIEW_DESC * desc,ID3D11Resource * resource,ID3D11ShaderResourceView ** resourceOut)216 HRESULT CreateResource(ID3D11Device *device,
217                        const D3D11_SHADER_RESOURCE_VIEW_DESC *desc,
218                        ID3D11Resource *resource,
219                        ID3D11ShaderResourceView **resourceOut)
220 {
221     return device->CreateShaderResourceView(resource, desc, resourceOut);
222 }
223 
CreateResource(ID3D11Device * device,const D3D11_UNORDERED_ACCESS_VIEW_DESC * desc,ID3D11Resource * resource,ID3D11UnorderedAccessView ** resourceOut)224 HRESULT CreateResource(ID3D11Device *device,
225                        const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc,
226                        ID3D11Resource *resource,
227                        ID3D11UnorderedAccessView **resourceOut)
228 {
229     return device->CreateUnorderedAccessView(resource, desc, resourceOut);
230 }
231 
CreateResource(ID3D11Device * device,const D3D11_TEXTURE2D_DESC * desc,const D3D11_SUBRESOURCE_DATA * initData,ID3D11Texture2D ** texture)232 HRESULT CreateResource(ID3D11Device *device,
233                        const D3D11_TEXTURE2D_DESC *desc,
234                        const D3D11_SUBRESOURCE_DATA *initData,
235                        ID3D11Texture2D **texture)
236 {
237     return device->CreateTexture2D(desc, initData, texture);
238 }
239 
CreateResource(ID3D11Device * device,const D3D11_TEXTURE3D_DESC * desc,const D3D11_SUBRESOURCE_DATA * initData,ID3D11Texture3D ** texture)240 HRESULT CreateResource(ID3D11Device *device,
241                        const D3D11_TEXTURE3D_DESC *desc,
242                        const D3D11_SUBRESOURCE_DATA *initData,
243                        ID3D11Texture3D **texture)
244 {
245     return device->CreateTexture3D(desc, initData, texture);
246 }
247 
CreateResource(ID3D11Device * device,const ShaderData * desc,void *,ID3D11VertexShader ** resourceOut)248 HRESULT CreateResource(ID3D11Device *device,
249                        const ShaderData *desc,
250                        void * /*initData*/,
251                        ID3D11VertexShader **resourceOut)
252 {
253     return device->CreateVertexShader(desc->get(), desc->size(), nullptr, resourceOut);
254 }
255 
GetTypedDepthStencilFormat(DXGI_FORMAT dxgiFormat)256 DXGI_FORMAT GetTypedDepthStencilFormat(DXGI_FORMAT dxgiFormat)
257 {
258     switch (dxgiFormat)
259     {
260         case DXGI_FORMAT_R16_TYPELESS:
261             return DXGI_FORMAT_D16_UNORM;
262         case DXGI_FORMAT_R24G8_TYPELESS:
263             return DXGI_FORMAT_D24_UNORM_S8_UINT;
264         case DXGI_FORMAT_R32_TYPELESS:
265             return DXGI_FORMAT_D32_FLOAT;
266         case DXGI_FORMAT_R32G8X24_TYPELESS:
267             return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
268         default:
269             return dxgiFormat;
270     }
271 }
272 
273 template <typename DescT, typename ResourceT>
ClearResource(d3d::Context * context,Renderer11 * renderer,const DescT * desc,ResourceT * texture)274 angle::Result ClearResource(d3d::Context *context,
275                             Renderer11 *renderer,
276                             const DescT *desc,
277                             ResourceT *texture)
278 {
279     // No-op.
280     return angle::Result::Continue;
281 }
282 
283 template <>
ClearResource(d3d::Context * context,Renderer11 * renderer,const D3D11_TEXTURE2D_DESC * desc,ID3D11Texture2D * texture)284 angle::Result ClearResource(d3d::Context *context,
285                             Renderer11 *renderer,
286                             const D3D11_TEXTURE2D_DESC *desc,
287                             ID3D11Texture2D *texture)
288 {
289     ID3D11DeviceContext *deviceContext = renderer->getDeviceContext();
290 
291     if ((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0)
292     {
293         D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
294         dsvDesc.Flags  = 0;
295         dsvDesc.Format = GetTypedDepthStencilFormat(desc->Format);
296 
297         const auto &format = d3d11_angle::GetFormat(dsvDesc.Format);
298         UINT clearFlags    = (format.depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
299                           (format.stencilBits > 0 ? D3D11_CLEAR_STENCIL : 0);
300 
301         // Must process each mip level individually.
302         for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
303         {
304             if (desc->SampleDesc.Count == 0)
305             {
306                 dsvDesc.Texture2D.MipSlice = mipLevel;
307                 dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
308             }
309             else
310             {
311                 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
312             }
313 
314             d3d11::DepthStencilView dsv;
315             ANGLE_TRY(renderer->allocateResource(context, dsvDesc, texture, &dsv));
316 
317             deviceContext->ClearDepthStencilView(dsv.get(), clearFlags, kDebugDepthInitValue,
318                                                  kDebugStencilInitValue);
319         }
320     }
321     else
322     {
323         ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
324         d3d11::RenderTargetView rtv;
325         ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv));
326 
327         deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
328     }
329 
330     return angle::Result::Continue;
331 }
332 
333 template <>
ClearResource(d3d::Context * context,Renderer11 * renderer,const D3D11_TEXTURE3D_DESC * desc,ID3D11Texture3D * texture)334 angle::Result ClearResource(d3d::Context *context,
335                             Renderer11 *renderer,
336                             const D3D11_TEXTURE3D_DESC *desc,
337                             ID3D11Texture3D *texture)
338 {
339     ID3D11DeviceContext *deviceContext = renderer->getDeviceContext();
340 
341     ASSERT((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0);
342     ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
343 
344     d3d11::RenderTargetView rtv;
345     ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv));
346 
347     deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
348     return angle::Result::Continue;
349 }
350 
351 #define ANGLE_RESOURCE_STRINGIFY_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
352     "Error allocating " #RESTYPE,
353 
354 constexpr std::array<const char *, NumResourceTypes> kResourceTypeErrors = {
355     {ANGLE_RESOURCE_TYPE_OP(Stringify, ANGLE_RESOURCE_STRINGIFY_OP)}};
356 static_assert(kResourceTypeErrors[NumResourceTypes - 1] != nullptr,
357               "All members must be initialized.");
358 
359 }  // anonymous namespace
360 
361 // ResourceManager11 Implementation.
ResourceManager11()362 ResourceManager11::ResourceManager11() : mInitializeAllocations(false)
363 {
364     for (auto &count : mAllocatedResourceCounts)
365     {
366         count = 0;
367     }
368     for (auto &memorySize : mAllocatedResourceDeviceMemory)
369     {
370         memorySize = 0;
371     }
372 }
373 
~ResourceManager11()374 ResourceManager11::~ResourceManager11()
375 {
376     for (size_t count : mAllocatedResourceCounts)
377     {
378         ASSERT(count == 0);
379     }
380 
381     for (uint64_t memorySize : mAllocatedResourceDeviceMemory)
382     {
383         ASSERT(memorySize == 0);
384     }
385 }
386 
387 template <typename T>
allocate(d3d::Context * context,Renderer11 * renderer,const GetDescFromD3D11<T> * desc,GetInitDataFromD3D11<T> * initData,Resource11<T> * resourceOut)388 angle::Result ResourceManager11::allocate(d3d::Context *context,
389                                           Renderer11 *renderer,
390                                           const GetDescFromD3D11<T> *desc,
391                                           GetInitDataFromD3D11<T> *initData,
392                                           Resource11<T> *resourceOut)
393 {
394     ID3D11Device *device = renderer->getDevice();
395     T *resource          = nullptr;
396 
397     GetInitDataFromD3D11<T> *shadowInitData = initData;
398     if (!shadowInitData && mInitializeAllocations)
399     {
400         shadowInitData = createInitDataIfNeeded<T>(desc);
401     }
402 
403     HRESULT hr = CreateResource(device, desc, shadowInitData, &resource);
404     ANGLE_TRY_HR(context, hr, kResourceTypeErrors[ResourceTypeIndex<T>()]);
405 
406     if (!shadowInitData && mInitializeAllocations)
407     {
408         ANGLE_TRY(ClearResource(context, renderer, desc, resource));
409     }
410 
411     ASSERT(resource);
412     incrResource(GetResourceTypeFromD3D11<T>(), ComputeMemoryUsage(desc));
413     *resourceOut = std::move(Resource11<T>(resource, this));
414     return angle::Result::Continue;
415 }
416 
incrResource(ResourceType resourceType,uint64_t memorySize)417 void ResourceManager11::incrResource(ResourceType resourceType, uint64_t memorySize)
418 {
419     size_t typeIndex = ResourceTypeIndex(resourceType);
420 
421     mAllocatedResourceCounts[typeIndex]++;
422     mAllocatedResourceDeviceMemory[typeIndex] += memorySize;
423 
424     // This checks for integer overflow.
425     ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
426     ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
427 }
428 
decrResource(ResourceType resourceType,uint64_t memorySize)429 void ResourceManager11::decrResource(ResourceType resourceType, uint64_t memorySize)
430 {
431     size_t typeIndex = ResourceTypeIndex(resourceType);
432 
433     ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
434     mAllocatedResourceCounts[typeIndex]--;
435     ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
436     mAllocatedResourceDeviceMemory[typeIndex] -= memorySize;
437 }
438 
onReleaseGeneric(ResourceType resourceType,ID3D11DeviceChild * resource)439 void ResourceManager11::onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource)
440 {
441     ASSERT(resource);
442     decrResource(resourceType, ComputeGenericMemoryUsage(resourceType, resource));
443 }
444 
445 template <>
createInitDataIfNeeded(const D3D11_TEXTURE2D_DESC * desc)446 const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded<ID3D11Texture2D>(
447     const D3D11_TEXTURE2D_DESC *desc)
448 {
449     ASSERT(desc);
450 
451     if ((desc->BindFlags & (D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_RENDER_TARGET)) != 0)
452     {
453         // This will be done using ClearView methods.
454         return nullptr;
455     }
456 
457     size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
458     if (mZeroMemory.size() < requiredSize)
459     {
460         if (!mZeroMemory.resize(requiredSize))
461         {
462             ERR() << "Failed to allocate D3D texture initialization data.";
463             return nullptr;
464         }
465         mZeroMemory.fill(kDebugInitTextureDataValue);
466     }
467 
468     const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
469 
470     UINT subresourceCount = desc->MipLevels * desc->ArraySize;
471     if (mShadowInitData.size() < subresourceCount)
472     {
473         mShadowInitData.resize(subresourceCount);
474     }
475 
476     for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
477     {
478         for (UINT arrayIndex = 0; arrayIndex < desc->ArraySize; ++arrayIndex)
479         {
480             UINT subresourceIndex = D3D11CalcSubresource(mipLevel, arrayIndex, desc->MipLevels);
481             D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex];
482 
483             UINT levelWidth  = std::max(desc->Width >> mipLevel, 1u);
484             UINT levelHeight = std::max(desc->Height >> mipLevel, 1u);
485 
486             data->SysMemPitch      = levelWidth * formatSizeInfo.pixelBytes;
487             data->SysMemSlicePitch = data->SysMemPitch * levelHeight;
488             data->pSysMem          = mZeroMemory.data();
489         }
490     }
491 
492     return mShadowInitData.data();
493 }
494 
495 template <>
createInitDataIfNeeded(const D3D11_TEXTURE3D_DESC * desc)496 const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded<ID3D11Texture3D>(
497     const D3D11_TEXTURE3D_DESC *desc)
498 {
499     ASSERT(desc);
500 
501     if ((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0)
502     {
503         // This will be done using ClearView methods.
504         return nullptr;
505     }
506 
507     size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
508     if (mZeroMemory.size() < requiredSize)
509     {
510         if (!mZeroMemory.resize(requiredSize))
511         {
512             ERR() << "Failed to allocate D3D texture initialization data.";
513             return nullptr;
514         }
515         mZeroMemory.fill(kDebugInitTextureDataValue);
516     }
517 
518     const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
519 
520     UINT subresourceCount = desc->MipLevels;
521     if (mShadowInitData.size() < subresourceCount)
522     {
523         mShadowInitData.resize(subresourceCount);
524     }
525 
526     for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
527     {
528         UINT subresourceIndex        = D3D11CalcSubresource(mipLevel, 0, desc->MipLevels);
529         D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex];
530 
531         UINT levelWidth  = std::max(desc->Width >> mipLevel, 1u);
532         UINT levelHeight = std::max(desc->Height >> mipLevel, 1u);
533 
534         data->SysMemPitch      = levelWidth * formatSizeInfo.pixelBytes;
535         data->SysMemSlicePitch = data->SysMemPitch * levelHeight;
536         data->pSysMem          = mZeroMemory.data();
537     }
538 
539     return mShadowInitData.data();
540 }
541 
542 template <typename T>
createInitDataIfNeeded(const GetDescFromD3D11<T> * desc)543 GetInitDataFromD3D11<T> *ResourceManager11::createInitDataIfNeeded(const GetDescFromD3D11<T> *desc)
544 {
545     // No-op.
546     return nullptr;
547 }
548 
setAllocationsInitialized(bool initialize)549 void ResourceManager11::setAllocationsInitialized(bool initialize)
550 {
551     mInitializeAllocations = initialize;
552 }
553 
554 #define ANGLE_INSTANTIATE_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
555                                                                                \
556     template angle::Result ResourceManager11::allocate(                        \
557         d3d::Context *, Renderer11 *, const DESCTYPE *, INITDATATYPE *, Resource11<D3D11TYPE> *);
558 
559 ANGLE_RESOURCE_TYPE_OP(Instantitate, ANGLE_INSTANTIATE_OP)
560 }  // namespace rx
561