aboutsummaryrefslogtreecommitdiff
path: root/lib/win32/Effects11/Binary/SOParser.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/win32/Effects11/Binary/SOParser.h')
-rw-r--r--lib/win32/Effects11/Binary/SOParser.h319
1 files changed, 319 insertions, 0 deletions
diff --git a/lib/win32/Effects11/Binary/SOParser.h b/lib/win32/Effects11/Binary/SOParser.h
new file mode 100644
index 0000000000..e8ef281f24
--- /dev/null
+++ b/lib/win32/Effects11/Binary/SOParser.h
@@ -0,0 +1,319 @@
+//--------------------------------------------------------------------------------------
+// File: SOParser.h
+//
+// Direct3D 11 Effects Stream Out Decl Parser
+//
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
+// PARTICULAR PURPOSE.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// http://go.microsoft.com/fwlink/p/?LinkId=271568
+//--------------------------------------------------------------------------------------
+
+#pragma once
+
+#include <stdio.h>
+#include <string.h>
+
+namespace D3DX11Effects
+{
+
+//////////////////////////////////////////////////////////////////////////
+// CSOParser
+//////////////////////////////////////////////////////////////////////////
+
+class CSOParser
+{
+
+ CEffectVector<D3D11_SO_DECLARATION_ENTRY> m_vDecls; // Set of parsed decl entries
+ D3D11_SO_DECLARATION_ENTRY m_newEntry; // Currently parsing entry
+ LPSTR m_SemanticString[D3D11_SO_BUFFER_SLOT_COUNT]; // Copy of strings
+
+ static const size_t MAX_ERROR_SIZE = 254;
+ char m_pError[ MAX_ERROR_SIZE + 1 ]; // Error buffer
+
+public:
+ CSOParser()
+ {
+ ZeroMemory(&m_newEntry, sizeof(m_newEntry));
+ ZeroMemory(m_SemanticString, sizeof(m_SemanticString));
+ m_pError[0] = 0;
+ }
+
+ ~CSOParser()
+ {
+ for( size_t Stream = 0; Stream < D3D11_SO_STREAM_COUNT; ++Stream )
+ {
+ SAFE_DELETE_ARRAY( m_SemanticString[Stream] );
+ }
+ }
+
+ // Parse a single string, assuming stream 0
+ HRESULT Parse( _In_z_ LPCSTR pString )
+ {
+ m_vDecls.Clear();
+ return Parse( 0, pString );
+ }
+
+ // Parse all 4 streams
+ HRESULT Parse( _In_z_ LPSTR pStreams[D3D11_SO_STREAM_COUNT] )
+ {
+ HRESULT hr = S_OK;
+ m_vDecls.Clear();
+ for( uint32_t iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
+ {
+ hr = Parse( iDecl, pStreams[iDecl] );
+ if( FAILED(hr) )
+ {
+ char str[16];
+ sprintf_s( str, 16, " in stream %u.", iDecl );
+ str[15] = 0;
+ strcat_s( m_pError, MAX_ERROR_SIZE, str );
+ return hr;
+ }
+ }
+ return hr;
+ }
+
+ // Return resulting declarations
+ D3D11_SO_DECLARATION_ENTRY *GetDeclArray()
+ {
+ return &m_vDecls[0];
+ }
+
+ char* GetErrorString()
+ {
+ return m_pError;
+ }
+
+ uint32_t GetDeclCount() const
+ {
+ return m_vDecls.GetSize();
+ }
+
+ // Return resulting buffer strides
+ void GetStrides( uint32_t strides[4] )
+ {
+ size_t len = GetDeclCount();
+ strides[0] = strides[1] = strides[2] = strides[3] = 0;
+
+ for( size_t i=0; i < len; i++ )
+ {
+ strides[m_vDecls[i].OutputSlot] += m_vDecls[i].ComponentCount * sizeof(float);
+ }
+ }
+
+protected:
+
+ // Parse a single string "[<slot> :] <semantic>[<index>][.<mask>]; [[<slot> :] <semantic>[<index>][.<mask>][;]]"
+ HRESULT Parse( _In_ uint32_t Stream, _In_z_ LPCSTR pString )
+ {
+ HRESULT hr = S_OK;
+
+ m_pError[0] = 0;
+
+ if( pString == nullptr )
+ return S_OK;
+
+ uint32_t len = (uint32_t)strlen( pString );
+ if( len == 0 )
+ return S_OK;
+
+ SAFE_DELETE_ARRAY( m_SemanticString[Stream] );
+ VN( m_SemanticString[Stream] = new char[len + 1] );
+ strcpy_s( m_SemanticString[Stream], len + 1, pString );
+
+ LPSTR pSemantic = m_SemanticString[Stream];
+
+ while( true )
+ {
+ // Each decl entry is delimited by a semi-colon
+ LPSTR pSemi = strchr( pSemantic, ';' );
+
+ // strip leading and trailing spaces
+ LPSTR pEnd;
+ if( pSemi != nullptr )
+ {
+ *pSemi = '\0';
+ pEnd = pSemi - 1;
+ }
+ else
+ {
+ pEnd = pSemantic + strlen( pSemantic );
+ }
+ while( isspace( (unsigned char)*pSemantic ) )
+ pSemantic++;
+ while( pEnd > pSemantic && isspace( (unsigned char)*pEnd ) )
+ {
+ *pEnd = '\0';
+ pEnd--;
+ }
+
+ if( *pSemantic != '\0' )
+ {
+ VH( AddSemantic( pSemantic ) );
+ m_newEntry.Stream = Stream;
+
+ VH( m_vDecls.Add( m_newEntry ) );
+ }
+ if( pSemi == nullptr )
+ break;
+ pSemantic = pSemi + 1;
+ }
+
+lExit:
+ return hr;
+ }
+
+ // Parse a single decl "[<slot> :] <semantic>[<index>][.<mask>]"
+ HRESULT AddSemantic( _Inout_z_ LPSTR pSemantic )
+ {
+ HRESULT hr = S_OK;
+
+ assert( pSemantic );
+
+ ZeroMemory( &m_newEntry, sizeof(m_newEntry) );
+ VH( ConsumeOutputSlot( &pSemantic ) );
+ VH( ConsumeRegisterMask( pSemantic ) );
+ VH( ConsumeSemanticIndex( pSemantic ) );
+
+ // pSenantic now contains only the SemanticName (all other fields were consumed)
+ if( strcmp( "$SKIP", pSemantic ) != 0 )
+ {
+ m_newEntry.SemanticName = pSemantic;
+ }
+
+lExit:
+ return hr;
+ }
+
+ // Parse optional mask "[.<mask>]"
+ HRESULT ConsumeRegisterMask( _Inout_z_ LPSTR pSemantic )
+ {
+ HRESULT hr = S_OK;
+ const char *pFullMask1 = "xyzw";
+ const char *pFullMask2 = "rgba";
+ size_t stringLength;
+ size_t startComponent = 0;
+ LPCSTR p;
+
+ assert( pSemantic );
+
+ pSemantic = strchr( pSemantic, '.' );
+
+ if( pSemantic == nullptr )
+ {
+ m_newEntry.ComponentCount = 4;
+ return S_OK;
+ }
+
+ *pSemantic = '\0';
+ pSemantic++;
+
+ stringLength = strlen( pSemantic );
+ p = strstr(pFullMask1, pSemantic );
+ if( p )
+ {
+ startComponent = (uint32_t)( p - pFullMask1 );
+ }
+ else
+ {
+ p = strstr( pFullMask2, pSemantic );
+ if( p )
+ startComponent = (uint32_t)( p - pFullMask2 );
+ else
+ {
+ sprintf_s( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - invalid mask declaration '%s'", pSemantic );
+ VH( E_FAIL );
+ }
+
+ }
+
+ if( stringLength == 0 )
+ stringLength = 4;
+
+ m_newEntry.StartComponent = (uint8_t)startComponent;
+ m_newEntry.ComponentCount = (uint8_t)stringLength;
+
+lExit:
+ return hr;
+ }
+
+ // Parse optional output slot "[<slot> :]"
+ HRESULT ConsumeOutputSlot( _Inout_z_ LPSTR* ppSemantic )
+ {
+ assert( ppSemantic && *ppSemantic );
+ _Analysis_assume_( ppSemantic && *ppSemantic );
+
+ HRESULT hr = S_OK;
+ LPSTR pColon = strchr( *ppSemantic, ':' );
+
+ if( pColon == nullptr )
+ return S_OK;
+
+ if( pColon == *ppSemantic )
+ {
+ strcpy_s( m_pError, MAX_ERROR_SIZE,
+ "ID3D11Effect::ParseSODecl - Invalid output slot" );
+ VH( E_FAIL );
+ }
+
+ *pColon = '\0';
+ int outputSlot = atoi( *ppSemantic );
+ if( outputSlot < 0 || outputSlot > 255 )
+ {
+ strcpy_s( m_pError, MAX_ERROR_SIZE,
+ "ID3D11Effect::ParseSODecl - Invalid output slot" );
+ VH( E_FAIL );
+ }
+ m_newEntry.OutputSlot = (uint8_t)outputSlot;
+
+ while( *ppSemantic < pColon )
+ {
+ if( !isdigit( (unsigned char)**ppSemantic ) )
+ {
+ sprintf_s( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - Non-digit '%c' in output slot", **ppSemantic );
+ VH( E_FAIL );
+ }
+ (*ppSemantic)++;
+ }
+
+ // skip the colon (which is now '\0')
+ (*ppSemantic)++;
+
+ while( isspace( (unsigned char)**ppSemantic ) )
+ (*ppSemantic)++;
+
+lExit:
+ return hr;
+ }
+
+ // Parse optional index "[<index>]"
+ HRESULT ConsumeSemanticIndex( _Inout_z_ LPSTR pSemantic )
+ {
+ assert( pSemantic );
+
+ uint32_t uLen = (uint32_t)strlen( pSemantic );
+
+ // Grab semantic index
+ while( uLen > 0 && isdigit( (unsigned char)pSemantic[uLen - 1] ) )
+ uLen--;
+
+ if( isdigit( (unsigned char)pSemantic[uLen] ) )
+ {
+ m_newEntry.SemanticIndex = atoi( pSemantic + uLen );
+ pSemantic[uLen] = '\0';
+ }
+ else
+ {
+ m_newEntry.SemanticIndex = 0;
+ }
+
+ return S_OK;
+ }
+};
+
+} // end namespace D3DX11Effects