diff options
Diffstat (limited to 'materialsystem/shaderapidx9/inputlayoutdx10.cpp')
| -rw-r--r-- | materialsystem/shaderapidx9/inputlayoutdx10.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/materialsystem/shaderapidx9/inputlayoutdx10.cpp b/materialsystem/shaderapidx9/inputlayoutdx10.cpp new file mode 100644 index 0000000..9482907 --- /dev/null +++ b/materialsystem/shaderapidx9/inputlayoutdx10.cpp @@ -0,0 +1,214 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#include <d3d10.h> +#undef GetCommandLine + +#include "inputlayoutdx10.h" +#include "materialsystem/imesh.h" +#include "shaderdevicedx10.h" + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Standard input layouts +//----------------------------------------------------------------------------- +static const DXGI_FORMAT s_pSizeLookup[] = +{ + DXGI_FORMAT_UNKNOWN, // Should be unused... + DXGI_FORMAT_R32_FLOAT, // D3DDECLTYPE_FLOAT1 + DXGI_FORMAT_R32G32_FLOAT, // D3DDECLTYPE_FLOAT2, + DXGI_FORMAT_R32G32B32_FLOAT, // D3DDECLTYPE_FLOAT3, + DXGI_FORMAT_R32G32B32A32_FLOAT, // D3DDECLTYPE_FLOAT4 +}; + +struct FieldInfo_t +{ + const char *m_pSemanticString; + unsigned int m_nSemanticIndex; + uint64 m_nFormatMask; + int m_nFieldSize; +}; + +static FieldInfo_t s_pFieldInfo[] = +{ + { "POSITION", 0, VERTEX_POSITION, sizeof( float ) * 3 }, + { "BLENDWEIGHT", 0, VERTEX_BONE_WEIGHT_MASK, 0 }, + { "BLENDINDICES", 0, VERTEX_BONE_INDEX, 4 }, + { "NORMAL", 0, VERTEX_NORMAL, sizeof( float ) * 3 }, + { "COLOR", 0, VERTEX_COLOR, 4 }, + { "SPECULAR", 0, VERTEX_SPECULAR, 4 }, + { "TEXCOORD", 0, VERTEX_TEXCOORD_MASK(0), 0 }, + { "TEXCOORD", 1, VERTEX_TEXCOORD_MASK(1), 0 }, + { "TEXCOORD", 2, VERTEX_TEXCOORD_MASK(2), 0 }, + { "TEXCOORD", 3, VERTEX_TEXCOORD_MASK(3), 0 }, + { "TEXCOORD", 4, VERTEX_TEXCOORD_MASK(4), 0 }, + { "TEXCOORD", 5, VERTEX_TEXCOORD_MASK(5), 0 }, + { "TEXCOORD", 6, VERTEX_TEXCOORD_MASK(6), 0 }, + { "TEXCOORD", 7, VERTEX_TEXCOORD_MASK(7), 0 }, + { "TANGENT", 0, VERTEX_TANGENT_S, sizeof( float ) * 3 }, + { "BINORMAL", 0, VERTEX_TANGENT_T, sizeof( float ) * 3 }, + { "USERDATA", 0, USER_DATA_SIZE_MASK, 0 }, + { NULL, 0, 0 }, +}; + +static D3D10_INPUT_ELEMENT_DESC s_pVertexDesc[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "BLENDWEIGHT", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "SPECULAR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 1, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 2, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 3, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 4, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 5, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 6, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 7, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "USERDATA", 0, DXGI_FORMAT_UNKNOWN, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, +}; + +static D3D10_INPUT_ELEMENT_DESC s_pFallbackVertexDesc[] = +{ + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 0, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BLENDWEIGHT", 0, DXGI_FORMAT_R32G32_FLOAT, 15, 12, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 15, 20, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 24, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 15, 36, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "SPECULAR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 15, 40, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 15, 44, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 15, 52, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 15, 60, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 3, DXGI_FORMAT_R32G32_FLOAT, 15, 68, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 4, DXGI_FORMAT_R32G32_FLOAT, 15, 76, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 5, DXGI_FORMAT_R32G32_FLOAT, 15, 84, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 6, DXGI_FORMAT_R32G32_FLOAT, 15, 92, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TEXCOORD", 7, DXGI_FORMAT_R32G32_FLOAT, 15, 100, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 108, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 15, 120, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, + { "USERDATA", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 15, 132, D3D10_INPUT_PER_INSTANCE_DATA, UINT_MAX }, +}; + + +//----------------------------------------------------------------------------- +// Computes the required input desc based on the vertex format +//----------------------------------------------------------------------------- +static void PrintInputDesc( int nCount, const D3D10_INPUT_ELEMENT_DESC *pDecl ) +{ + for ( int i = 0; i < nCount; i++ ) + { + Msg( "%s (%d): Stream: %d, Offset: %d, Instanced? %c\n", + pDecl[i].SemanticName, + pDecl[i].SemanticIndex, + ( int )pDecl[i].InputSlot, + ( int )pDecl[i].AlignedByteOffset, + pDecl[i].InputSlotClass == D3D10_INPUT_PER_VERTEX_DATA ? 'n' : 'y' + ); + } +} + + +//----------------------------------------------------------------------------- +// Checks to see if a shader requires a particular field +//----------------------------------------------------------------------------- +static bool CheckShaderSignatureExpectations( ID3D10ShaderReflection* pReflection, const char* pSemantic, unsigned int nSemanticIndex ) +{ + D3D10_SHADER_DESC shaderDesc; + D3D10_SIGNATURE_PARAMETER_DESC paramDesc; + + Assert( pSemantic ); + Assert( pReflection ); + + pReflection->GetDesc( &shaderDesc ); + + for ( unsigned int k=0; k < shaderDesc.InputParameters; k++ ) + { + pReflection->GetInputParameterDesc( k, ¶mDesc ); + if ( ( nSemanticIndex == paramDesc.SemanticIndex ) && !Q_stricmp( pSemantic, paramDesc.SemanticName ) ) + return true; + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Computes the required input desc based on the vertex format +//----------------------------------------------------------------------------- +static unsigned int ComputeInputDesc( VertexFormat_t fmt, D3D10_INPUT_ELEMENT_DESC *pDecl, ID3D10ShaderReflection* pReflection ) +{ + unsigned int nCount = 0; + int nOffset = 0; + + // Fix up the global table so we don't need special-case code + int nBoneCount = NumBoneWeights( fmt ); + s_pFieldInfo[1].m_nFieldSize = sizeof( float ) * nBoneCount; + s_pVertexDesc[1].Format = s_pSizeLookup[ nBoneCount ]; + + int nUserDataSize = UserDataSize( fmt ); + s_pFieldInfo[16].m_nFieldSize = sizeof( float ) * nUserDataSize; + s_pVertexDesc[16].Format = s_pSizeLookup[ nUserDataSize ]; + + // NOTE: Fix s_pFieldInfo, s_pVertexDesc, s_pFallbackVertexDesc if you add more fields + // As well as the fallback stream (stream #15) + COMPILE_TIME_ASSERT( VERTEX_MAX_TEXTURE_COORDINATES == 8 ); + for ( int i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i ) + { + int nTexCoordCount = TexCoordSize( i, fmt ); + s_pFieldInfo[6+i].m_nFieldSize = sizeof( float ) * nTexCoordCount; + s_pVertexDesc[6+i].Format = s_pSizeLookup[ nTexCoordCount ]; + } + + // FIXME: Change this loop so CheckShaderSignatureExpectations is called once! + for ( int i = 0; s_pFieldInfo[i].m_pSemanticString; ++i ) + { + if ( fmt & s_pFieldInfo[i].m_nFormatMask ) + { + memcpy( &pDecl[nCount], &s_pVertexDesc[i], sizeof(D3D10_INPUT_ELEMENT_DESC) ); + pDecl[nCount].AlignedByteOffset = nOffset; + nOffset += s_pFieldInfo[i].m_nFieldSize; + ++nCount; + } + else if ( CheckShaderSignatureExpectations( pReflection, s_pFieldInfo[i].m_pSemanticString, s_pFieldInfo[i].m_nSemanticIndex ) ) + { + memcpy( &pDecl[nCount], &s_pFallbackVertexDesc[i], sizeof(D3D10_INPUT_ELEMENT_DESC) ); + ++nCount; + } + } + + // For debugging only... +// PrintInputDesc( nCount, pDecl ); + + return nCount; +} + + +//----------------------------------------------------------------------------- +// Gets the input layout associated with a vertex format +//----------------------------------------------------------------------------- +ID3D10InputLayout *CreateInputLayout( VertexFormat_t fmt, ID3D10ShaderReflection* pReflection, const void *pByteCode, size_t nByteCodeLen ) +{ + D3D10_INPUT_ELEMENT_DESC pDecl[32]; + unsigned int nDeclCount = ComputeInputDesc( fmt, pDecl, pReflection ); + + ID3D10InputLayout *pInputLayout; + HRESULT hr = D3D10Device()->CreateInputLayout( pDecl, nDeclCount, pByteCode, nByteCodeLen, &pInputLayout ); + if ( FAILED( hr ) ) + { + Warning( "CreateInputLayout::Unable to create input layout for format %llX!\n", fmt ); + return NULL; + } + return pInputLayout; +} |