]> git.cworth.org Git - apitrace/blob - helpers/d3d10size.hpp
d3d10: Take mip level in consideration.
[apitrace] / helpers / d3d10size.hpp
1 /**************************************************************************
2  *
3  * Copyright 2012 Jose Fonseca
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sub license,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  * 
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  * 
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20  * AUTHORS,
21  * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *
26  **************************************************************************/
27
28
29 /*
30  * Auxiliary functions to compute the size of array/blob arguments.
31  */
32
33 #ifndef _D3D10SIZE_HPP_
34 #define _D3D10SIZE_HPP_
35
36
37 /* We purposedly don't include any D3D header, so that this header can be used
38  * with all D3D versions. */
39
40 #include <assert.h>
41
42 #include <algorithm>
43
44
45 static size_t
46 _calcDataSize(DXGI_FORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth = 1, INT DepthPitch = 0) {
47     if (Width == 0 || Height == 0 || Depth == 0) {
48         return 0;
49     }
50
51     if (RowPitch < 0) {
52         os::log("apitrace: warning: %s: negative row pitch %i\n", __FUNCTION__, RowPitch);
53         return 0;
54     }
55
56     if (DepthPitch < 0) {
57         os::log("apitrace: warning: %s: negative slice pitch %i\n", __FUNCTION__, DepthPitch);
58         return 0;
59     }
60
61     switch (Format) {
62     case DXGI_FORMAT_BC1_TYPELESS:
63     case DXGI_FORMAT_BC1_UNORM:
64     case DXGI_FORMAT_BC1_UNORM_SRGB:
65     case DXGI_FORMAT_BC2_TYPELESS:
66     case DXGI_FORMAT_BC2_UNORM:
67     case DXGI_FORMAT_BC2_UNORM_SRGB:
68     case DXGI_FORMAT_BC3_TYPELESS:
69     case DXGI_FORMAT_BC3_UNORM:
70     case DXGI_FORMAT_BC3_UNORM_SRGB:
71     case DXGI_FORMAT_BC4_TYPELESS:
72     case DXGI_FORMAT_BC4_UNORM:
73     case DXGI_FORMAT_BC4_SNORM:
74     case DXGI_FORMAT_BC5_TYPELESS:
75     case DXGI_FORMAT_BC5_UNORM:
76     case DXGI_FORMAT_BC5_SNORM:
77         Width  = (Width  + 3) / 4;
78         Height = (Height + 3) / 4;
79         break;
80
81     case DXGI_FORMAT_R8G8_B8G8_UNORM:
82     case DXGI_FORMAT_G8R8_G8B8_UNORM:
83         Width = (Width + 1) / 2;
84         break;
85
86     case DXGI_FORMAT_UNKNOWN:
87         return 0;
88
89     default:
90         break;
91     }
92
93     /* FIXME */
94     (void)Width;
95
96     size_t size = Height * RowPitch;
97
98     if (Depth > 1) {
99         size += (Depth - 1) * DepthPitch;
100     }
101
102     return size;
103 }
104
105 static size_t
106 _calcMipDataSize(UINT MipLevel, DXGI_FORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth = 1, INT DepthPitch = 0) {
107     if (Width == 0 || Height == 0 || Depth == 0) {
108         return 0;
109     }
110
111     Width  = std::max(Width  >> MipLevel, UINT(1));
112     Height = std::max(Height >> MipLevel, UINT(1));
113     Depth  = std::max(Depth  >> MipLevel, UINT(1));
114
115     return _calcDataSize(Format, Width, Height, RowPitch, Depth, DepthPitch);
116 }
117
118
119 inline UINT
120 _getNumMipLevels(UINT Width, UINT Height = 1, UINT Depth = 1) {
121     UINT MipLevels = 0;
122     do {
123         ++MipLevels;
124         Width  >>= 1;
125         Height >>= 1;
126         Depth  >>= 1;
127     } while (Width || Height || Depth);
128     return MipLevels;
129 }
130
131 inline UINT
132 _getNumMipLevels(const D3D10_BUFFER_DESC *pDesc) {
133     return 1;
134 }
135
136 inline UINT
137 _getNumMipLevels(const D3D10_TEXTURE1D_DESC *pDesc) {
138     return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width);
139 }
140
141 inline UINT
142 _getNumMipLevels(const D3D10_TEXTURE2D_DESC *pDesc) {
143     return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width, pDesc->Height);
144 }
145
146 inline UINT
147 _getNumMipLevels(const D3D10_TEXTURE3D_DESC *pDesc) {
148     return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width, pDesc->Height, pDesc->Depth);
149 }
150
151 inline UINT
152 _getNumSubResources(const D3D10_BUFFER_DESC *pDesc) {
153     return 1;
154 }
155
156 inline UINT
157 _getNumSubResources(const D3D10_TEXTURE1D_DESC *pDesc) {
158     return _getNumMipLevels(pDesc) * pDesc->ArraySize;
159 }
160
161 inline UINT
162 _getNumSubResources(const D3D10_TEXTURE2D_DESC *pDesc) {
163     return _getNumMipLevels(pDesc) * pDesc->ArraySize;
164 }
165
166 inline UINT
167 _getNumSubResources(const D3D10_TEXTURE3D_DESC *pDesc) {
168     return _getNumMipLevels(pDesc);
169 }
170
171 static inline void
172 _getMapInfo(ID3D10Buffer *pResource, D3D10_MAP MapType, UINT MapFlags, void * * ppData,
173             void * & pMappedData, size_t & MappedSize) {
174     pMappedData = 0;
175     MappedSize = 0;
176
177     if (MapType == D3D10_MAP_READ) {
178         return;
179     }
180
181     D3D10_BUFFER_DESC Desc;
182     pResource->GetDesc(&Desc);
183
184     pMappedData = *ppData;
185     MappedSize = Desc.ByteWidth;
186 }
187
188 static inline void
189 _getMapInfo(ID3D10Texture1D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, void * * ppData,
190             void * & pMappedData, size_t & MappedSize) {
191     pMappedData = 0;
192     MappedSize = 0;
193
194     if (MapType == D3D10_MAP_READ) {
195         return;
196     }
197
198     D3D10_TEXTURE1D_DESC Desc;
199     pResource->GetDesc(&Desc);
200
201     UINT MipLevel = Subresource % _getNumMipLevels(&Desc);
202
203     pMappedData = *ppData;
204     MappedSize = _calcMipDataSize(MipLevel, Desc.Format, Desc.Width, 1, 0);
205 }
206
207 static inline void
208 _getMapInfo(ID3D10Texture2D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE2D * pMappedTex2D,
209             void * & pMappedData, size_t & MappedSize) {
210     pMappedData = 0;
211     MappedSize = 0;
212
213     if (MapType == D3D10_MAP_READ) {
214         return;
215     }
216
217     D3D10_TEXTURE2D_DESC Desc;
218     pResource->GetDesc(&Desc);
219
220     UINT MipLevel = Subresource % _getNumMipLevels(&Desc);
221
222     pMappedData = pMappedTex2D->pData;
223     MappedSize = _calcMipDataSize(MipLevel, Desc.Format, Desc.Width, Desc.Height, pMappedTex2D->RowPitch);
224 }
225
226 static inline void
227 _getMapInfo(ID3D10Texture3D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE3D * pMappedTex3D,
228             void * & pMappedData, size_t & MappedSize) {
229     pMappedData = 0;
230     MappedSize = 0;
231
232     if (MapType == D3D10_MAP_READ) {
233         return;
234     }
235
236     D3D10_TEXTURE3D_DESC Desc;
237     pResource->GetDesc(&Desc);
238
239     UINT MipLevel = Subresource;
240
241     pMappedData = pMappedTex3D->pData;
242     MappedSize = _calcMipDataSize(MipLevel, Desc.Format, Desc.Width, Desc.Height, pMappedTex3D->RowPitch, Desc.Depth, pMappedTex3D->DepthPitch);
243 }
244
245
246 static inline void
247 _getMapInfo(IDXGISurface *pResource, DXGI_MAPPED_RECT * pLockedRect, UINT MapFlags,
248             void * & pMappedData, size_t & MappedSize) {
249     pMappedData = 0;
250     MappedSize = 0;
251
252     if (!(MapFlags & DXGI_MAP_WRITE)) {
253         return;
254     }
255
256     DXGI_SURFACE_DESC Desc;
257     HRESULT hr = pResource->GetDesc(&Desc);
258     if (FAILED(hr)) {
259         return;
260     }
261
262     pMappedData = pLockedRect->pBits;
263     MappedSize = _calcDataSize(Desc.Format, Desc.Width, Desc.Height, pLockedRect->Pitch);
264 }
265
266
267 #endif /* _D3D10SIZE_HPP_ */