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)30size_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()41MappedSubresourceVerifier11::~MappedSubresourceVerifier11() 42 { 43 ASSERT(!mOrigData); 44 ASSERT(!mWrapData.size()); 45 } 46 setDesc(const D3D11_TEXTURE2D_DESC & desc)47void 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)60void 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()74void 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)82bool 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()105void 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