]> git.cworth.org Git - apitrace/blob - helpers/d3dsize.hpp
9f662971f21cc82a7745bd3cc96770383da23e04
[apitrace] / helpers / d3dsize.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 _D3D_SIZE_HPP_
34 #define _D3D_SIZE_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 "os.hpp"
43
44
45 static inline size_t
46 _vertexCount(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
47 {
48     switch (PrimitiveType) {
49     case D3DPT_POINTLIST:
50         return PrimitiveCount;
51     case D3DPT_LINELIST:
52         return PrimitiveCount*2;
53     case D3DPT_LINESTRIP:
54         return PrimitiveCount + 1;
55     case D3DPT_TRIANGLELIST:
56         return PrimitiveCount * 3;
57     case D3DPT_TRIANGLESTRIP:
58         return PrimitiveCount + 2;
59     case D3DPT_TRIANGLEFAN:
60         return PrimitiveCount + 1;
61     default:
62         os::log("apitrace: warning: %s: unknown D3DPRIMITIVETYPE %u\n", __FUNCTION__, PrimitiveType);
63         return 0;
64     }
65 }
66
67
68 static inline size_t
69 _vertexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, UINT VertexStride) {
70     return _vertexCount(PrimitiveType, PrimitiveCount) * VertexStride;
71 }
72
73
74 static inline size_t
75 _indexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, D3DFORMAT IndexDataFormat) {
76     UINT IndexStride;
77     switch (IndexDataFormat) {
78     case D3DFMT_INDEX16:
79         IndexStride = 2;
80         break;
81     case D3DFMT_INDEX32:
82         IndexStride = 4;
83         break;
84     default:
85         os::log("apitrace: warning: %s: unexpected index D3DFORMAT %u\n", __FUNCTION__, IndexDataFormat);
86         return 0;
87     }
88     return _vertexCount(PrimitiveType, PrimitiveCount) * IndexStride;
89 }
90
91
92 #if DIRECT3D_VERSION >= 0x0800
93
94 /*
95  * Return the number of tokens for a given shader.
96  */
97 static inline size_t
98 _shaderSize(const DWORD *pFunction)
99 {
100     DWORD dwLength = 0;
101
102     while (true) {
103         DWORD dwToken = pFunction[dwLength++];
104
105         switch (dwToken & D3DSI_OPCODE_MASK) {
106         case D3DSIO_COMMENT:
107             dwLength += (dwToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
108             break;
109
110         case D3DSIO_END:
111             if (dwToken != D3DSIO_END) {
112                 os::log("apitrace: warning: %s: malformed END token\n", __FUNCTION__);
113             }
114             return dwLength * sizeof *pFunction;
115         }
116     }
117 }
118
119
120 static size_t
121 _getLockSize(D3DFORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth = 1, INT SlicePitch = 0) {
122     if (Width == 0 || Height == 0 || Depth == 0) {
123         return 0;
124     }
125
126     if (RowPitch < 0) {
127         os::log("apitrace: warning: %s: negative row pitch %i\n", __FUNCTION__, RowPitch);
128         return 0;
129     }
130
131     if (SlicePitch < 0) {
132         os::log("apitrace: warning: %s: negative slice pitch %i\n", __FUNCTION__, SlicePitch);
133         return 0;
134     }
135
136     switch ((DWORD)Format) {
137     case D3DFMT_DXT1:
138     case D3DFMT_DXT2:
139     case D3DFMT_DXT3:
140     case D3DFMT_DXT4:
141     case D3DFMT_DXT5:
142         Width  = (Width  + 3) / 4;
143         Height = (Height + 3) / 4;
144         break;
145
146     case D3DFMT_ATI1N:
147     case D3DFMT_ATI2N:
148         /*
149          * Because these are unsupported formats, RowPitch is not set to the
150          * number of bytes between row of blocks, but instead in such way that
151          * Height * RowPitch will match the expected size.
152          */
153         break;
154
155     case D3DFMT_UYVY:
156     case D3DFMT_R8G8_B8G8:
157     case D3DFMT_YUY2:
158     case D3DFMT_G8R8_G8B8:
159         Width = (Width + 1) / 2;
160         break;
161
162     case D3DFMT_NV12:
163         return (Height + ((Height + 1) / 2)) * RowPitch;
164
165     case D3DFMT_NULL:
166         return 0;
167
168     default:
169         break;
170     }
171
172     (void)Width;
173
174     size_t size = Height * RowPitch;
175
176     if (Depth > 1) {
177         size += (Depth - 1) * SlicePitch;
178     }
179
180     return size;
181 }
182
183
184 #endif /* DIRECT3D_VERSION >= 0x0800 */
185
186
187 #if DIRECT3D_VERSION >= 0x0900
188
189
190 static inline size_t
191 _getLockSize(IDirect3DVertexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData) {
192     if (SizeToLock == 0) {
193         D3DVERTEXBUFFER_DESC Desc;
194         HRESULT hr = pBuffer->GetDesc(&Desc);
195         if (FAILED(hr)) {
196             return 0;
197         } 
198         SizeToLock = Desc.Size;
199     }
200
201     return SizeToLock;
202 }
203
204
205 static inline size_t
206 _getLockSize(IDirect3DIndexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData) {
207     if (SizeToLock == 0) {
208         D3DINDEXBUFFER_DESC Desc;
209         HRESULT hr = pBuffer->GetDesc(&Desc);
210         if (FAILED(hr)) {
211             return 0;
212         } 
213         SizeToLock = Desc.Size;
214     }
215
216     return SizeToLock;
217 }
218
219
220 static inline size_t
221 _getLockSize(IDirect3DSurface9 *pSurface, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect) {
222     HRESULT hr;
223
224     D3DSURFACE_DESC Desc;
225     hr = pSurface->GetDesc(&Desc);
226     if (FAILED(hr)) {
227         return 0;
228     } 
229
230     UINT Width;
231     UINT Height;
232     if (pRect) {
233         Width  = pRect->right  - pRect->left;
234         Height = pRect->bottom - pRect->top;
235     } else {
236         Width  = Desc.Width;
237         Height = Desc.Height;
238     }
239
240     return _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
241 }
242
243
244 static inline size_t
245 _getLockSize(IDirect3DTexture9 *pTexture, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect) {
246     HRESULT hr;
247
248     D3DSURFACE_DESC Desc;
249     hr = pTexture->GetLevelDesc(Level, &Desc);
250     if (FAILED(hr)) {
251         return 0;
252     }
253
254     UINT Width;
255     UINT Height;
256     if (pRect) {
257         Width  = pRect->right  - pRect->left;
258         Height = pRect->bottom - pRect->top;
259     } else {
260         Width  = Desc.Width;
261         Height = Desc.Height;
262     }
263
264     return _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
265 }
266
267
268 static inline size_t
269 _getLockSize(IDirect3DCubeTexture9 *pTexture, D3DCUBEMAP_FACES FaceType, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect) {
270     HRESULT hr;
271
272     (void)FaceType;
273
274     D3DSURFACE_DESC Desc;
275     hr = pTexture->GetLevelDesc(Level, &Desc);
276     if (FAILED(hr)) {
277         return 0;
278     }
279
280     UINT Width;
281     UINT Height;
282     if (pRect) {
283         Width  = pRect->right  - pRect->left;
284         Height = pRect->bottom - pRect->top;
285     } else {
286         Width  = Desc.Width;
287         Height = Desc.Height;
288     }
289
290     return _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
291 }
292
293
294 static inline size_t
295 _getLockSize(IDirect3DVolume9 *pVolume, const D3DLOCKED_BOX *pLockedBox, const D3DBOX *pBox) {
296     HRESULT hr;
297
298     D3DVOLUME_DESC Desc;
299     hr = pVolume->GetDesc(&Desc);
300     if (FAILED(hr)) {
301         return 0;
302     }
303
304     UINT Width;
305     UINT Height;
306     UINT Depth;
307     if (pBox) {
308         Width  = pBox->Right  - pBox->Left;
309         Height = pBox->Bottom - pBox->Top;
310         Depth  = pBox->Back   - pBox->Front;
311     } else {
312         Width  = Desc.Width;
313         Height = Desc.Height;
314         Depth  = Desc.Depth;
315     }
316
317     return _getLockSize(Desc.Format, Width, Height, pLockedBox->RowPitch, Depth, pLockedBox->SlicePitch);
318 }
319
320
321 static inline size_t
322 _getLockSize(IDirect3DVolumeTexture9 *pTexture, UINT Level, const D3DLOCKED_BOX *pLockedBox, const D3DBOX *pBox) {
323     HRESULT hr;
324
325     D3DVOLUME_DESC Desc;
326     hr = pTexture->GetLevelDesc(Level, &Desc);
327     if (FAILED(hr)) {
328         return 0;
329     }
330
331     UINT Width;
332     UINT Height;
333     UINT Depth;
334     if (pBox) {
335         Width  = pBox->Right  - pBox->Left;
336         Height = pBox->Bottom - pBox->Top;
337         Depth  = pBox->Back   - pBox->Front;
338     } else {
339         Width  = Desc.Width;
340         Height = Desc.Height;
341         Depth  = Desc.Depth;
342     }
343
344     return _getLockSize(Desc.Format, Width, Height, pLockedBox->RowPitch, Depth, pLockedBox->SlicePitch);
345 }
346
347
348 #endif /* DIRECT3D_VERSION >= 0x0900 */
349
350
351 #endif /* _D3D_SIZE_HPP_ */