1 //////////////////////////////////////////////////////////////////////////////
\r
3 // Copyright (C) Microsoft Corporation. All Rights Reserved.
\r
6 // Content: D3DX11 Effects Stream Out Decl Parser
\r
8 //////////////////////////////////////////////////////////////////////////////
\r
12 namespace D3DX11Effects
\r
16 //////////////////////////////////////////////////////////////////////////
\r
18 //////////////////////////////////////////////////////////////////////////
\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
27 static const UINT MAX_ERROR_SIZE = 254;
\r
28 char m_pError[ MAX_ERROR_SIZE + 1 ]; // Error buffer
\r
33 ZeroMemory(&m_newEntry, sizeof(m_newEntry));
\r
34 ZeroMemory(m_SemanticString, sizeof(m_SemanticString));
\r
40 for( UINT Stream = 0; Stream < D3D11_SO_STREAM_COUNT; Stream++ )
\r
42 SAFE_DELETE_ARRAY( m_SemanticString[Stream] );
\r
46 // Parse a single string, assuming stream 0
\r
47 HRESULT Parse( __in_z LPCSTR pString )
\r
50 return Parse( 0, pString );
\r
53 // Parse all 4 streams
\r
54 HRESULT Parse( __in_z LPSTR pStreams[D3D11_SO_STREAM_COUNT] )
\r
58 for( UINT iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
\r
60 hr = Parse( iDecl, pStreams[iDecl] );
\r
64 StringCchPrintfA( pStream, 16, " in stream %d.", iDecl );
\r
66 StringCchCatA( m_pError, MAX_ERROR_SIZE, pStream );
\r
73 // Return resulting declarations
\r
74 D3D11_SO_DECLARATION_ENTRY *GetDeclArray()
\r
76 return &m_vDecls[0];
\r
79 char* GetErrorString()
\r
84 UINT GetDeclCount() const
\r
86 return m_vDecls.GetSize();
\r
89 // Return resulting buffer strides
\r
90 void GetStrides( UINT strides[4] )
\r
92 UINT len = GetDeclCount();
\r
93 strides[0] = strides[1] = strides[2] = strides[3] = 0;
\r
95 for( UINT i=0; i < len; i++ )
\r
97 strides[m_vDecls[i].OutputSlot] += m_vDecls[i].ComponentCount * sizeof(float);
\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
110 if( pString == NULL )
\r
113 UINT len = (UINT)strlen( pString );
\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
121 LPSTR pSemantic = m_SemanticString[Stream];
\r
125 // Each decl entry is delimited by a semi-colon
\r
126 LPSTR pSemi = strchr( pSemantic, ';' );
\r
128 // strip leading and trailing spaces
\r
130 if( pSemi != NULL )
\r
137 pEnd = pSemantic + strlen( pSemantic );
\r
139 while( isspace( (unsigned char)*pSemantic ) )
\r
141 while( pEnd > pSemantic && isspace( (unsigned char)*pEnd ) )
\r
147 if( *pSemantic != '\0' )
\r
149 VH( AddSemantic( pSemantic ) );
\r
150 m_newEntry.Stream = Stream;
\r
152 VH( m_vDecls.Add( m_newEntry ) );
\r
154 if( pSemi == NULL )
\r
156 pSemantic = pSemi + 1;
\r
163 // Parse a single decl "[<slot> :] <semantic>[<index>][.<mask>]"
\r
164 HRESULT AddSemantic( __inout_z LPSTR pSemantic )
\r
168 D3DXASSERT( pSemantic );
\r
170 ZeroMemory( &m_newEntry, sizeof(m_newEntry) );
\r
171 VH( ConsumeOutputSlot( &pSemantic ) );
\r
172 VH( ConsumeRegisterMask( pSemantic ) );
\r
173 VH( ConsumeSemanticIndex( pSemantic ) );
\r
175 // pSenantic now contains only the SemanticName (all other fields were consumed)
\r
176 if( strcmp( "$SKIP", pSemantic ) != 0 )
\r
178 m_newEntry.SemanticName = pSemantic;
\r
185 // Parse optional mask "[.<mask>]"
\r
186 HRESULT ConsumeRegisterMask( __inout_z LPSTR pSemantic )
\r
189 const char *pFullMask1 = "xyzw";
\r
190 const char *pFullMask2 = "rgba";
\r
191 SIZE_T stringLength;
\r
192 SIZE_T startComponent = 0;
\r
195 D3DXASSERT( pSemantic );
\r
197 pSemantic = strchr( pSemantic, '.' );
\r
199 if( pSemantic == NULL )
\r
201 m_newEntry.ComponentCount = 4;
\r
208 stringLength = strlen( pSemantic );
\r
209 p = strstr(pFullMask1, pSemantic );
\r
212 startComponent = (UINT)( p - pFullMask1 );
\r
216 p = strstr( pFullMask2, pSemantic );
\r
218 startComponent = (UINT)( p - pFullMask2 );
\r
221 StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - invalid mask declaration '%s'", pSemantic );
\r
227 if( stringLength == 0 )
\r
230 m_newEntry.StartComponent = (BYTE)startComponent;
\r
231 m_newEntry.ComponentCount = (BYTE)stringLength;
\r
237 // Parse optional output slot "[<slot> :]"
\r
238 HRESULT ConsumeOutputSlot( __deref_inout_z LPSTR* ppSemantic )
\r
240 D3DXASSERT( ppSemantic && *ppSemantic );
\r
243 LPSTR pColon = strchr( *ppSemantic, ':' );
\r
245 if( pColon == NULL )
\r
248 if( pColon == *ppSemantic )
\r
250 StringCchCopyA( m_pError, MAX_ERROR_SIZE,
\r
251 "ID3D11Effect::ParseSODecl - Invalid output slot" );
\r
256 int outputSlot = atoi( *ppSemantic );
\r
257 if( outputSlot < 0 || outputSlot > 255 )
\r
259 StringCchCopyA( m_pError, MAX_ERROR_SIZE,
\r
260 "ID3D11Effect::ParseSODecl - Invalid output slot" );
\r
263 m_newEntry.OutputSlot = (BYTE)outputSlot;
\r
265 while( *ppSemantic < pColon )
\r
267 if( !isdigit( (unsigned char)**ppSemantic ) )
\r
269 StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - Non-digit '%c' in output slot", **ppSemantic );
\r
275 // skip the colon (which is now '\0')
\r
278 while( isspace( (unsigned char)**ppSemantic ) )
\r
285 // Parse optional index "[<index>]"
\r
286 HRESULT ConsumeSemanticIndex( __inout_z LPSTR pSemantic )
\r
288 D3DXASSERT( pSemantic );
\r
290 UINT uLen = (UINT)strlen( pSemantic );
\r
292 // Grab semantic index
\r
293 while( uLen > 0 && isdigit( (unsigned char)pSemantic[uLen - 1] ) )
\r
296 if( isdigit( (unsigned char)pSemantic[uLen] ) )
\r
298 m_newEntry.SemanticIndex = atoi( pSemantic + uLen );
\r
299 pSemantic[uLen] = '\0';
\r
303 m_newEntry.SemanticIndex = 0;
\r
311 } // end namespace D3DX11Effects
\r