OSDN Git Service

f3f8ba6c396dacc9fe97a391e5bfe0166e7ad6df
[dtxmania/dtxmania.git] / SlimDXc_Jun2010(VC++2008) / external / Effects11 / Binary / SOParser.h
1 //////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 //  Copyright (C) Microsoft Corporation.  All Rights Reserved.\r
4 //\r
5 //  File:       SOParser.h\r
6 //  Content:    D3DX11 Effects Stream Out Decl Parser\r
7 //\r
8 //////////////////////////////////////////////////////////////////////////////\r
9 \r
10 #pragma once\r
11 \r
12 namespace D3DX11Effects\r
13 {\r
14 \r
15 \r
16 //////////////////////////////////////////////////////////////////////////\r
17 // CSOParser\r
18 //////////////////////////////////////////////////////////////////////////\r
19 \r
20 class CSOParser\r
21 {\r
22 \r
23     CEffectVector<D3D11_SO_DECLARATION_ENTRY>   m_vDecls;                                       // Set of parsed decl entries\r
24     D3D11_SO_DECLARATION_ENTRY                  m_newEntry;                                     // Currently parsing entry\r
25     LPSTR                                       m_SemanticString[D3D11_SO_BUFFER_SLOT_COUNT];   // Copy of strings\r
26 \r
27     static const UINT MAX_ERROR_SIZE = 254;\r
28     char                                        m_pError[ MAX_ERROR_SIZE + 1 ];                 // Error buffer\r
29 \r
30 public:\r
31     CSOParser()\r
32     {\r
33         ZeroMemory(&m_newEntry, sizeof(m_newEntry));\r
34         ZeroMemory(m_SemanticString, sizeof(m_SemanticString));\r
35         m_pError[0] = 0;\r
36     }\r
37 \r
38     ~CSOParser()\r
39     {\r
40         for( UINT Stream = 0; Stream < D3D11_SO_STREAM_COUNT; Stream++ )\r
41         {\r
42             SAFE_DELETE_ARRAY( m_SemanticString[Stream] );\r
43         }\r
44     }\r
45 \r
46     // Parse a single string, assuming stream 0\r
47     HRESULT Parse( __in_z LPCSTR pString )\r
48     {\r
49         m_vDecls.Clear();\r
50         return Parse( 0, pString );\r
51     }\r
52 \r
53     // Parse all 4 streams\r
54     HRESULT Parse( __in_z LPSTR pStreams[D3D11_SO_STREAM_COUNT] )\r
55     {\r
56         HRESULT hr = S_OK;\r
57         m_vDecls.Clear();\r
58         for( UINT iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )\r
59         {\r
60             hr = Parse( iDecl, pStreams[iDecl] );\r
61             if( FAILED(hr) )\r
62             {\r
63                 char pStream[16];\r
64                 StringCchPrintfA( pStream, 16, " in stream %d.", iDecl );\r
65                 pStream[15] = 0;\r
66                 StringCchCatA( m_pError, MAX_ERROR_SIZE, pStream );\r
67                 return hr;\r
68             }\r
69         }\r
70         return hr;\r
71     }\r
72 \r
73     // Return resulting declarations\r
74     D3D11_SO_DECLARATION_ENTRY *GetDeclArray()\r
75     {\r
76         return &m_vDecls[0];\r
77     }\r
78 \r
79     char* GetErrorString()\r
80     {\r
81         return m_pError;\r
82     }\r
83 \r
84     UINT GetDeclCount() const\r
85     {\r
86         return m_vDecls.GetSize();\r
87     }\r
88 \r
89     // Return resulting buffer strides\r
90     void GetStrides( UINT strides[4] )\r
91     {\r
92         UINT len = GetDeclCount();\r
93         strides[0] = strides[1] = strides[2] = strides[3] = 0;\r
94 \r
95         for( UINT i=0; i < len; i++ )\r
96         {\r
97             strides[m_vDecls[i].OutputSlot] += m_vDecls[i].ComponentCount * sizeof(float);\r
98         }\r
99     }\r
100 \r
101 protected:\r
102 \r
103     // Parse a single string "[<slot> :] <semantic>[<index>][.<mask>]; [[<slot> :] <semantic>[<index>][.<mask>][;]]"\r
104     HRESULT Parse( UINT Stream, __in_z LPCSTR pString )\r
105     {\r
106         HRESULT hr = S_OK;\r
107 \r
108         m_pError[0] = 0;\r
109 \r
110         if( pString == NULL )\r
111             return S_OK;\r
112 \r
113         UINT len = (UINT)strlen( pString );\r
114         if( len == 0 )\r
115             return S_OK;\r
116 \r
117         SAFE_DELETE_ARRAY( m_SemanticString[Stream] );\r
118         VN( m_SemanticString[Stream] = NEW char[len + 1] );\r
119         StringCchCopyA( m_SemanticString[Stream], len + 1, pString );\r
120 \r
121         LPSTR pSemantic = m_SemanticString[Stream];\r
122 \r
123         while( TRUE )\r
124         {\r
125             // Each decl entry is delimited by a semi-colon\r
126             LPSTR pSemi = strchr( pSemantic, ';' );\r
127 \r
128             // strip leading and trailing spaces\r
129             LPSTR pEnd;\r
130             if( pSemi != NULL )\r
131             {\r
132                 *pSemi = '\0';\r
133                 pEnd = pSemi - 1;\r
134             }\r
135             else\r
136             {\r
137                 pEnd = pSemantic + strlen( pSemantic );\r
138             }\r
139             while( isspace( (unsigned char)*pSemantic ) )\r
140                 pSemantic++;\r
141             while( pEnd > pSemantic && isspace( (unsigned char)*pEnd ) )\r
142             {\r
143                 *pEnd = '\0';\r
144                 pEnd--;\r
145             }\r
146 \r
147             if( *pSemantic != '\0' )\r
148             {\r
149                 VH( AddSemantic( pSemantic ) );\r
150                 m_newEntry.Stream = Stream;\r
151 \r
152                 VH( m_vDecls.Add( m_newEntry ) );\r
153             }\r
154             if( pSemi == NULL )\r
155                 break;\r
156             pSemantic = pSemi + 1;\r
157         }\r
158 \r
159 lExit:\r
160         return hr;\r
161     }\r
162 \r
163     // Parse a single decl  "[<slot> :] <semantic>[<index>][.<mask>]"\r
164     HRESULT AddSemantic( __inout_z LPSTR pSemantic )\r
165     {\r
166         HRESULT hr = S_OK;\r
167 \r
168         D3DXASSERT( pSemantic );\r
169 \r
170         ZeroMemory( &m_newEntry, sizeof(m_newEntry) );\r
171         VH( ConsumeOutputSlot( &pSemantic ) );\r
172         VH( ConsumeRegisterMask( pSemantic ) );\r
173         VH( ConsumeSemanticIndex( pSemantic ) );\r
174 \r
175         // pSenantic now contains only the SemanticName (all other fields were consumed)\r
176         if( strcmp( "$SKIP", pSemantic ) != 0 )\r
177         {\r
178             m_newEntry.SemanticName = pSemantic;\r
179         }\r
180 \r
181 lExit:\r
182         return hr;\r
183     }\r
184 \r
185     // Parse optional mask "[.<mask>]"\r
186     HRESULT ConsumeRegisterMask( __inout_z LPSTR pSemantic )\r
187     {\r
188         HRESULT hr = S_OK;\r
189         const char *pFullMask1 = "xyzw";\r
190         const char *pFullMask2 = "rgba";\r
191         SIZE_T stringLength;\r
192         SIZE_T startComponent = 0;\r
193         LPCSTR p;\r
194 \r
195         D3DXASSERT( pSemantic );\r
196 \r
197         pSemantic = strchr( pSemantic, '.' ); \r
198 \r
199         if( pSemantic == NULL )\r
200         {\r
201             m_newEntry.ComponentCount = 4;\r
202             return S_OK;\r
203         }\r
204 \r
205         *pSemantic = '\0';\r
206         pSemantic++;\r
207 \r
208         stringLength = strlen( pSemantic );\r
209         p = strstr(pFullMask1, pSemantic );\r
210         if( p )\r
211         {\r
212             startComponent = (UINT)( p - pFullMask1 );\r
213         }\r
214         else\r
215         {\r
216             p = strstr( pFullMask2, pSemantic );\r
217             if( p )\r
218                 startComponent = (UINT)( p - pFullMask2 );\r
219             else\r
220             {\r
221                 StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - invalid mask declaration '%s'", pSemantic );\r
222                 VH( E_FAIL );\r
223             }\r
224 \r
225         }\r
226 \r
227         if( stringLength == 0 )\r
228             stringLength = 4;\r
229 \r
230         m_newEntry.StartComponent = (BYTE)startComponent;\r
231         m_newEntry.ComponentCount = (BYTE)stringLength;\r
232 \r
233 lExit:\r
234         return hr;\r
235     }\r
236 \r
237     // Parse optional output slot "[<slot> :]"\r
238     HRESULT ConsumeOutputSlot( __deref_inout_z LPSTR* ppSemantic )\r
239     {\r
240         D3DXASSERT( ppSemantic && *ppSemantic );\r
241 \r
242         HRESULT hr = S_OK;\r
243         LPSTR pColon = strchr( *ppSemantic, ':' ); \r
244 \r
245         if( pColon == NULL )\r
246             return S_OK;\r
247 \r
248         if( pColon == *ppSemantic )\r
249         {\r
250             StringCchCopyA( m_pError, MAX_ERROR_SIZE,\r
251                            "ID3D11Effect::ParseSODecl - Invalid output slot" );\r
252             VH( E_FAIL );\r
253         }\r
254 \r
255         *pColon = '\0';\r
256         int outputSlot = atoi( *ppSemantic );\r
257         if( outputSlot < 0 || outputSlot > 255 )\r
258         {\r
259             StringCchCopyA( m_pError, MAX_ERROR_SIZE,\r
260                            "ID3D11Effect::ParseSODecl - Invalid output slot" );\r
261             VH( E_FAIL );\r
262         }\r
263         m_newEntry.OutputSlot = (BYTE)outputSlot;\r
264 \r
265         while( *ppSemantic < pColon )\r
266         {\r
267             if( !isdigit( (unsigned char)**ppSemantic ) )\r
268             {\r
269                 StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - Non-digit '%c' in output slot", **ppSemantic );\r
270                 VH( E_FAIL );\r
271             }\r
272             (*ppSemantic)++;\r
273         }\r
274 \r
275         // skip the colon (which is now '\0')\r
276         (*ppSemantic)++;\r
277 \r
278         while( isspace( (unsigned char)**ppSemantic ) )\r
279             (*ppSemantic)++;\r
280 \r
281 lExit:\r
282         return hr;\r
283     }\r
284 \r
285     // Parse optional index "[<index>]"\r
286     HRESULT ConsumeSemanticIndex( __inout_z LPSTR pSemantic )\r
287     {\r
288         D3DXASSERT( pSemantic );\r
289 \r
290         UINT uLen = (UINT)strlen( pSemantic );\r
291 \r
292         // Grab semantic index\r
293         while( uLen > 0 && isdigit( (unsigned char)pSemantic[uLen - 1] ) )\r
294             uLen--;\r
295 \r
296         if( isdigit( (unsigned char)pSemantic[uLen] ) )\r
297         {\r
298             m_newEntry.SemanticIndex = atoi( pSemantic + uLen );\r
299             pSemantic[uLen] = '\0';\r
300         } \r
301         else\r
302         {\r
303             m_newEntry.SemanticIndex = 0;\r
304         }\r
305 \r
306         return S_OK;\r
307     }\r
308 };\r
309 \r
310 \r
311 } // end namespace D3DX11Effects\r