• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // MappedSubresourceVerifier11.cpp: Implements the
8 // rx::MappedSubresourceVerifier11 class, a simple wrapper to D3D11 Texture2D
9 // mapped memory so that ASAN and MSAN can catch memory errors done with a
10 // pointer to the mapped texture memory.
11 
12 #include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h"
13 
14 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
15 
16 namespace rx
17 {
18 
19 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)
20 
21 namespace
22 {
23 
24 #    if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
25 constexpr bool kUseWrap = true;
26 #    else
27 constexpr bool kUseWrap = false;
28 #    endif
29 
getPitchCount(const D3D11_TEXTURE2D_DESC & desc)30 size_t getPitchCount(const D3D11_TEXTURE2D_DESC &desc)
31 {
32     const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(desc.Format);
33     ASSERT(desc.Height % dxgiFormatInfo.blockHeight == 0);
34     return desc.Height / dxgiFormatInfo.blockHeight;
35 }
36 
37 }  // namespace
38 
39 MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default;
40 
~MappedSubresourceVerifier11()41 MappedSubresourceVerifier11::~MappedSubresourceVerifier11()
42 {
43     ASSERT(!mOrigData);
44     ASSERT(!mWrapData.size());
45 }
46 
setDesc(const D3D11_TEXTURE2D_DESC & desc)47 void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc)
48 {
49     ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
50     ASSERT(desc.Width);
51     ASSERT(desc.Height);
52     ASSERT(!mOrigData);
53     ASSERT(!mWrapData.size());
54     ASSERT(!mPitchType);
55     ASSERT(!mPitchCount);
56     mPitchType  = &D3D11_MAPPED_SUBRESOURCE::RowPitch;
57     mPitchCount = getPitchCount(desc);
58 }
59 
setDesc(const D3D11_TEXTURE3D_DESC & desc)60 void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc)
61 {
62     ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
63     ASSERT(desc.Width);
64     ASSERT(desc.Height);
65     ASSERT(desc.Depth);
66     ASSERT(!mOrigData);
67     ASSERT(!mWrapData.size());
68     ASSERT(!mPitchType);
69     ASSERT(!mPitchCount);
70     mPitchType  = &D3D11_MAPPED_SUBRESOURCE::DepthPitch;
71     mPitchCount = desc.Depth;
72 }
73 
reset()74 void MappedSubresourceVerifier11::reset()
75 {
76     ASSERT(!mOrigData);
77     ASSERT(!mWrapData.size());
78     mPitchType  = nullptr;
79     mPitchCount = 0;
80 }
81 
wrap(D3D11_MAP mapType,D3D11_MAPPED_SUBRESOURCE * map)82 bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
83 {
84     ASSERT(map && map->pData);
85     ASSERT(mapType == D3D11_MAP_READ || mapType == D3D11_MAP_WRITE ||
86            mapType == D3D11_MAP_READ_WRITE);
87     ASSERT(mPitchCount);
88 
89     if (kUseWrap)
90     {
91         if (!mWrapData.resize(mPitchCount * map->*mPitchType))
92             return false;
93     }
94 
95     mOrigData = reinterpret_cast<uint8_t *>(map->pData);
96 
97     if (kUseWrap)
98     {
99         std::copy(mOrigData, mOrigData + mWrapData.size(), mWrapData.data());
100         map->pData = mWrapData.data();
101     }
102     return true;
103 }
104 
unwrap()105 void MappedSubresourceVerifier11::unwrap()
106 {
107     ASSERT(mPitchCount);
108     ASSERT(mOrigData);
109     if (kUseWrap)
110     {
111         std::copy(mWrapData.data(), mWrapData.data() + mWrapData.size(), mOrigData);
112         mWrapData = angle::MemoryBuffer();
113     }
114     mOrigData = nullptr;
115 }
116 
117 #endif
118 
119 }  // namespace rx
120