+++ /dev/null
-//////////////////////////////////////////////////////////////////////////////\r
-//\r
-// Copyright (C) Microsoft Corporation. All Rights Reserved.\r
-//\r
-// File: SOParser.h\r
-// Content: D3DX11 Effects Stream Out Decl Parser\r
-//\r
-//////////////////////////////////////////////////////////////////////////////\r
-\r
-#pragma once\r
-\r
-namespace D3DX11Effects\r
-{\r
-\r
-\r
-//////////////////////////////////////////////////////////////////////////\r
-// CSOParser\r
-//////////////////////////////////////////////////////////////////////////\r
-\r
-class CSOParser\r
-{\r
-\r
- CEffectVector<D3D11_SO_DECLARATION_ENTRY> m_vDecls; // Set of parsed decl entries\r
- D3D11_SO_DECLARATION_ENTRY m_newEntry; // Currently parsing entry\r
- LPSTR m_SemanticString[D3D11_SO_BUFFER_SLOT_COUNT]; // Copy of strings\r
-\r
- static const UINT MAX_ERROR_SIZE = 254;\r
- char m_pError[ MAX_ERROR_SIZE + 1 ]; // Error buffer\r
-\r
-public:\r
- CSOParser()\r
- {\r
- ZeroMemory(&m_newEntry, sizeof(m_newEntry));\r
- ZeroMemory(m_SemanticString, sizeof(m_SemanticString));\r
- m_pError[0] = 0;\r
- }\r
-\r
- ~CSOParser()\r
- {\r
- for( UINT Stream = 0; Stream < D3D11_SO_STREAM_COUNT; Stream++ )\r
- {\r
- SAFE_DELETE_ARRAY( m_SemanticString[Stream] );\r
- }\r
- }\r
-\r
- // Parse a single string, assuming stream 0\r
- HRESULT Parse( __in_z LPCSTR pString )\r
- {\r
- m_vDecls.Clear();\r
- return Parse( 0, pString );\r
- }\r
-\r
- // Parse all 4 streams\r
- HRESULT Parse( __in_z LPSTR pStreams[D3D11_SO_STREAM_COUNT] )\r
- {\r
- HRESULT hr = S_OK;\r
- m_vDecls.Clear();\r
- for( UINT iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )\r
- {\r
- hr = Parse( iDecl, pStreams[iDecl] );\r
- if( FAILED(hr) )\r
- {\r
- char pStream[16];\r
- StringCchPrintfA( pStream, 16, " in stream %d.", iDecl );\r
- pStream[15] = 0;\r
- StringCchCatA( m_pError, MAX_ERROR_SIZE, pStream );\r
- return hr;\r
- }\r
- }\r
- return hr;\r
- }\r
-\r
- // Return resulting declarations\r
- D3D11_SO_DECLARATION_ENTRY *GetDeclArray()\r
- {\r
- return &m_vDecls[0];\r
- }\r
-\r
- char* GetErrorString()\r
- {\r
- return m_pError;\r
- }\r
-\r
- UINT GetDeclCount() const\r
- {\r
- return m_vDecls.GetSize();\r
- }\r
-\r
- // Return resulting buffer strides\r
- void GetStrides( UINT strides[4] )\r
- {\r
- UINT len = GetDeclCount();\r
- strides[0] = strides[1] = strides[2] = strides[3] = 0;\r
-\r
- for( UINT i=0; i < len; i++ )\r
- {\r
- strides[m_vDecls[i].OutputSlot] += m_vDecls[i].ComponentCount * sizeof(float);\r
- }\r
- }\r
-\r
-protected:\r
-\r
- // Parse a single string "[<slot> :] <semantic>[<index>][.<mask>]; [[<slot> :] <semantic>[<index>][.<mask>][;]]"\r
- HRESULT Parse( UINT Stream, __in_z LPCSTR pString )\r
- {\r
- HRESULT hr = S_OK;\r
-\r
- m_pError[0] = 0;\r
-\r
- if( pString == NULL )\r
- return S_OK;\r
-\r
- UINT len = (UINT)strlen( pString );\r
- if( len == 0 )\r
- return S_OK;\r
-\r
- SAFE_DELETE_ARRAY( m_SemanticString[Stream] );\r
- VN( m_SemanticString[Stream] = NEW char[len + 1] );\r
- StringCchCopyA( m_SemanticString[Stream], len + 1, pString );\r
-\r
- LPSTR pSemantic = m_SemanticString[Stream];\r
-\r
- while( TRUE )\r
- {\r
- // Each decl entry is delimited by a semi-colon\r
- LPSTR pSemi = strchr( pSemantic, ';' );\r
-\r
- // strip leading and trailing spaces\r
- LPSTR pEnd;\r
- if( pSemi != NULL )\r
- {\r
- *pSemi = '\0';\r
- pEnd = pSemi - 1;\r
- }\r
- else\r
- {\r
- pEnd = pSemantic + strlen( pSemantic );\r
- }\r
- while( isspace( (unsigned char)*pSemantic ) )\r
- pSemantic++;\r
- while( pEnd > pSemantic && isspace( (unsigned char)*pEnd ) )\r
- {\r
- *pEnd = '\0';\r
- pEnd--;\r
- }\r
-\r
- if( *pSemantic != '\0' )\r
- {\r
- VH( AddSemantic( pSemantic ) );\r
- m_newEntry.Stream = Stream;\r
-\r
- VH( m_vDecls.Add( m_newEntry ) );\r
- }\r
- if( pSemi == NULL )\r
- break;\r
- pSemantic = pSemi + 1;\r
- }\r
-\r
-lExit:\r
- return hr;\r
- }\r
-\r
- // Parse a single decl "[<slot> :] <semantic>[<index>][.<mask>]"\r
- HRESULT AddSemantic( __inout_z LPSTR pSemantic )\r
- {\r
- HRESULT hr = S_OK;\r
-\r
- D3DXASSERT( pSemantic );\r
-\r
- ZeroMemory( &m_newEntry, sizeof(m_newEntry) );\r
- VH( ConsumeOutputSlot( &pSemantic ) );\r
- VH( ConsumeRegisterMask( pSemantic ) );\r
- VH( ConsumeSemanticIndex( pSemantic ) );\r
-\r
- // pSenantic now contains only the SemanticName (all other fields were consumed)\r
- if( strcmp( "$SKIP", pSemantic ) != 0 )\r
- {\r
- m_newEntry.SemanticName = pSemantic;\r
- }\r
-\r
-lExit:\r
- return hr;\r
- }\r
-\r
- // Parse optional mask "[.<mask>]"\r
- HRESULT ConsumeRegisterMask( __inout_z LPSTR pSemantic )\r
- {\r
- HRESULT hr = S_OK;\r
- const char *pFullMask1 = "xyzw";\r
- const char *pFullMask2 = "rgba";\r
- SIZE_T stringLength;\r
- SIZE_T startComponent = 0;\r
- LPCSTR p;\r
-\r
- D3DXASSERT( pSemantic );\r
-\r
- pSemantic = strchr( pSemantic, '.' ); \r
-\r
- if( pSemantic == NULL )\r
- {\r
- m_newEntry.ComponentCount = 4;\r
- return S_OK;\r
- }\r
-\r
- *pSemantic = '\0';\r
- pSemantic++;\r
-\r
- stringLength = strlen( pSemantic );\r
- p = strstr(pFullMask1, pSemantic );\r
- if( p )\r
- {\r
- startComponent = (UINT)( p - pFullMask1 );\r
- }\r
- else\r
- {\r
- p = strstr( pFullMask2, pSemantic );\r
- if( p )\r
- startComponent = (UINT)( p - pFullMask2 );\r
- else\r
- {\r
- StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - invalid mask declaration '%s'", pSemantic );\r
- VH( E_FAIL );\r
- }\r
-\r
- }\r
-\r
- if( stringLength == 0 )\r
- stringLength = 4;\r
-\r
- m_newEntry.StartComponent = (BYTE)startComponent;\r
- m_newEntry.ComponentCount = (BYTE)stringLength;\r
-\r
-lExit:\r
- return hr;\r
- }\r
-\r
- // Parse optional output slot "[<slot> :]"\r
- HRESULT ConsumeOutputSlot( __deref_inout_z LPSTR* ppSemantic )\r
- {\r
- D3DXASSERT( ppSemantic && *ppSemantic );\r
-\r
- HRESULT hr = S_OK;\r
- LPSTR pColon = strchr( *ppSemantic, ':' ); \r
-\r
- if( pColon == NULL )\r
- return S_OK;\r
-\r
- if( pColon == *ppSemantic )\r
- {\r
- StringCchCopyA( m_pError, MAX_ERROR_SIZE,\r
- "ID3D11Effect::ParseSODecl - Invalid output slot" );\r
- VH( E_FAIL );\r
- }\r
-\r
- *pColon = '\0';\r
- int outputSlot = atoi( *ppSemantic );\r
- if( outputSlot < 0 || outputSlot > 255 )\r
- {\r
- StringCchCopyA( m_pError, MAX_ERROR_SIZE,\r
- "ID3D11Effect::ParseSODecl - Invalid output slot" );\r
- VH( E_FAIL );\r
- }\r
- m_newEntry.OutputSlot = (BYTE)outputSlot;\r
-\r
- while( *ppSemantic < pColon )\r
- {\r
- if( !isdigit( (unsigned char)**ppSemantic ) )\r
- {\r
- StringCchPrintfA( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - Non-digit '%c' in output slot", **ppSemantic );\r
- VH( E_FAIL );\r
- }\r
- (*ppSemantic)++;\r
- }\r
-\r
- // skip the colon (which is now '\0')\r
- (*ppSemantic)++;\r
-\r
- while( isspace( (unsigned char)**ppSemantic ) )\r
- (*ppSemantic)++;\r
-\r
-lExit:\r
- return hr;\r
- }\r
-\r
- // Parse optional index "[<index>]"\r
- HRESULT ConsumeSemanticIndex( __inout_z LPSTR pSemantic )\r
- {\r
- D3DXASSERT( pSemantic );\r
-\r
- UINT uLen = (UINT)strlen( pSemantic );\r
-\r
- // Grab semantic index\r
- while( uLen > 0 && isdigit( (unsigned char)pSemantic[uLen - 1] ) )\r
- uLen--;\r
-\r
- if( isdigit( (unsigned char)pSemantic[uLen] ) )\r
- {\r
- m_newEntry.SemanticIndex = atoi( pSemantic + uLen );\r
- pSemantic[uLen] = '\0';\r
- } \r
- else\r
- {\r
- m_newEntry.SemanticIndex = 0;\r
- }\r
-\r
- return S_OK;\r
- }\r
-};\r
-\r
-\r
-} // end namespace D3DX11Effects\r