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