Files
Totterynine 2773eae4d7 shaderapidx11
use -dxlevel 110 to use it
2021-09-22 18:56:56 +05:00

608 lines
19 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
// HUH???
#define RAD_TELEMETRY_DISABLED
#include "shadershadowdx11.h"
#include "utlvector.h"
#include "materialsystem/imaterialsystem.h"
#include "IHardwareConfigInternal.h"
//#include "shadersystem.h"
//#include "shaderapi/ishaderutil.h"
#include "shaderapidx11_global.h"
#include "materialsystem/imesh.h"
#include "tier0/dbg.h"
#include "materialsystem/idebugtextureinfo.h"
#include "vertexshaderdx11.h"
#include "shaderapidx11.h"
#include "shaderdevicedx11.h"
#include "meshdx11.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Class Factory
//-----------------------------------------------------------------------------
static CShaderShadowDx11 s_ShaderShadow;
CShaderShadowDx11 *g_pShaderShadowDx11 = &s_ShaderShadow;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderShadowDx11, IShaderShadow,
SHADERSHADOW_INTERFACE_VERSION, s_ShaderShadow )
//-----------------------------------------------------------------------------
// The shader shadow interface
//-----------------------------------------------------------------------------
CShaderShadowDx11::CShaderShadowDx11()
{
// Setup default shadow states
m_DefaultShadowState.desc.SetDefault();
m_DefaultCBState.SetDefault();
unsigned int iDefaultCB = FindOrCreateConstantBufferState( m_DefaultCBState );
m_DefaultShadowState.m_iGSConstantBufferState = iDefaultCB;
m_DefaultShadowState.m_iPSConstantBufferState = iDefaultCB;
m_DefaultShadowState.m_iVSConstantBufferState = iDefaultCB;
m_DefaultDepthStencilState.SetDefault();
m_DefaultRasterState.SetDefault();
m_DefaultBlendState.SetDefault();
}
CShaderShadowDx11::~CShaderShadowDx11()
{
}
// Sets the default *shadow* state
void CShaderShadowDx11::SetDefaultState()
{
m_ShadowState = StatesDx11::ShadowStateDesc();
m_ShadowState.SetDefault();
}
// Methods related to depth buffering
void CShaderShadowDx11::DepthFunc( ShaderDepthFunc_t depthFunc )
{
m_ShadowState.depthStencil.DepthFunc = (D3D11_COMPARISON_FUNC)depthFunc;
}
void CShaderShadowDx11::EnableDepthWrites( bool bEnable )
{
m_ShadowState.depthStencil.DepthWriteMask = bEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
}
void CShaderShadowDx11::EnableDepthTest( bool bEnable )
{
m_ShadowState.depthStencil.DepthEnable = bEnable;
}
void CShaderShadowDx11::EnablePolyOffset( PolygonOffsetMode_t nOffsetMode )
{
//m_ShadowState.rasterizer.DepthBias =
}
// Suppresses/activates color writing
void CShaderShadowDx11::EnableColorWrites( bool bEnable )
{
if ( bEnable )
{
m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask |=
D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN |
D3D11_COLOR_WRITE_ENABLE_BLUE;
}
else
{
m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask &=
~( D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN |
D3D11_COLOR_WRITE_ENABLE_BLUE );
}
}
// Suppresses/activates alpha writing
void CShaderShadowDx11::EnableAlphaWrites( bool bEnable )
{
if ( bEnable )
{
m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
}
else
{
m_ShadowState.blend.RenderTarget[0].RenderTargetWriteMask &= ~D3D11_COLOR_WRITE_ENABLE_ALPHA;
}
}
// Methods related to alpha blending
void CShaderShadowDx11::EnableBlending( bool bEnable )
{
m_ShadowState.blend.RenderTarget[0].BlendEnable = bEnable ? TRUE : FALSE;
}
void CShaderShadowDx11::BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor )
{
m_ShadowState.blend.RenderTarget[0].SrcBlend = TranslateD3D11BlendFunc( srcFactor );
m_ShadowState.blend.RenderTarget[0].DestBlend = TranslateD3D11BlendFunc( dstFactor );
}
// Alpha testing
// NOTE: Unused since alpha testing is no longer fixed-function in DX11.
// Just set an ALPHA_TEST combo in your shader and provide the
// reference value as a constant.
//
void CShaderShadowDx11::EnableAlphaTest( bool bEnable )
{
//m_ShadowState.bEnableAlphaTest = bEnable;
}
void CShaderShadowDx11::AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ )
{
//m_ShadowState.alphaTestFunc = alphaFunc;
//m_ShadowState.alphaTestRef = alphaRef;
}
// Wireframe/filled polygons
void CShaderShadowDx11::PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode )
{
D3D11_FILL_MODE mode;
switch ( polyMode )
{
case SHADER_POLYMODE_FILL:
mode = D3D11_FILL_SOLID;
break;
case SHADER_POLYMODE_LINE:
case SHADER_POLYMODE_POINT:
default:
mode = D3D11_FILL_WIREFRAME;
break;
}
m_ShadowState.rasterizer.FillMode = mode;
//m_ShadowState.rasterizer.CullMode =
//m_ShadowState.renderModeAttrib.polyMode = polyMode;
// m_ShadowState.renderModeAttrib.faceMode = face;
}
// Back face culling
void CShaderShadowDx11::EnableCulling( bool bEnable )
{
// DX11FIXME
//m_ShadowState.cullFaceAttrib.bEnable = bEnable;
m_ShadowState.rasterizer.CullMode = bEnable ? D3D11_CULL_BACK : D3D11_CULL_NONE;
//m_ShadowState.cullFaceAttrib.cullMode = MATERIAL_CULLMODE_CCW;
}
// constant color + transparency
void CShaderShadowDx11::EnableConstantColor( bool bEnable )
{
//m_ShadowState.bConstantColor = bEnable;
}
// Indicates the vertex format for use with a vertex shader
// The flags to pass in here come from the VertexFormatFlags_t enum
// If pTexCoordDimensions is *not* specified, we assume all coordinates
// are 2-dimensional
void CShaderShadowDx11::VertexShaderVertexFormat( unsigned int flags,
int numTexCoords, int* pTexCoordDimensions,
int userDataSize )
{
// Code that creates a Mesh should specify whether it contains bone weights+indices, *not* the shader.
Assert( ( flags & VERTEX_BONE_INDEX ) == 0 );
flags &= ~VERTEX_BONE_INDEX;
// This indicates we're using a vertex shader
flags |= VERTEX_FORMAT_VERTEX_SHADER;
m_ShadowState.vertexFormat = MeshMgr()->ComputeVertexFormat( flags, numTexCoords,
pTexCoordDimensions, 0, userDataSize );
// Avoid an error if vertex stream 0 is too narrow
if ( CVertexBufferBase::VertexFormatSize( m_ShadowState.vertexFormat ) <= 16 )
{
// FIXME: this is only necessary because we
// (a) put the flex normal/position stream in ALL vertex decls
// (b) bind stream 0's VB to stream 2 if there is no actual flex data
// ...it would be far more sensible to not add stream 2 to all vertex decls.
static bool bComplained = false;
if ( !bComplained )
{
Warning( "ERROR: shader asking for a too-narrow vertex format - you will see errors if running with debug D3D DLLs!\n\tPadding the vertex format with extra texcoords\n\tWill not warn again.\n" );
bComplained = true;
}
// All vertex formats should contain position...
Assert( flags & VERTEX_POSITION );
flags |= VERTEX_POSITION;
// This error should occur only if we have zero texcoords, or if we have a single, 1-D texcoord
Assert( ( userDataSize == 0 ) ||
( ( userDataSize == 1 ) && pTexCoordDimensions && ( pTexCoordDimensions[0] == 1 ) ) );
numTexCoords = 1;
m_ShadowState.vertexFormat = MeshMgr()->ComputeVertexFormat(
flags, numTexCoords, NULL, 0, userDataSize );
}
}
// Indicates we're going to light the model
void CShaderShadowDx11::EnableLighting( bool bEnable )
{
//m_ShadowState.bLighting = bEnable;
}
// Activate/deactivate skinning
void CShaderShadowDx11::EnableVertexBlend( bool bEnable )
{
// Activate/deactivate skinning. Indexed blending is automatically
// enabled if it's available for this hardware. When blending is enabled,
// we allocate enough room for 3 weights (max allowed)
//if ( ( HardwareConfig()->MaxBlendMatrices() > 0 ) || ( !bEnable ) )
//{
//m_ShadowState.bVertexBlend = bEnable;
//}
}
void CShaderShadowDx11::EnableTexture( Sampler_t sampler, bool bEnable )
{
//if ( sampler < HardwareConfig()->GetSamplerCount() )
//{
// m_ShadowState.samplerAttrib.EnableTexture( sampler, bEnable );
//}
//else
//{
// Warning( "Attempting to bind a texture to an invalid sampler (%d)!\n", sampler );
//}
}
// Sets the vertex and pixel shaders
void CShaderShadowDx11::SetVertexShader( const char *pShaderName, ShaderIndex_t vshIndex )
{
m_ShadowState.vertexShader = ShaderManager()->CreateVertexShader( pShaderName, vshIndex );
m_ShadowState.staticVertexShaderIndex = vshIndex;
}
void CShaderShadowDx11::EnableBlendingSeparateAlpha( bool bEnable )
{
// DX11FIXME
//m_ShadowState.m_SeparateAlphaBlendEnable = bEnable;
//m_ShadowState.colorBlendAttrib.bIndependentAlphaBlend = bEnable;
}
void CShaderShadowDx11::SetPixelShader( const char *pShaderName, ShaderIndex_t pshIndex )
{
m_ShadowState.pixelShader = ShaderManager()->CreatePixelShader( pShaderName, pshIndex );
m_ShadowState.staticPixelShaderIndex = pshIndex;
}
void CShaderShadowDx11::SetMorphFormat( MorphFormat_t flags )
{
m_ShadowState.morphFormat = flags;
}
void CShaderShadowDx11::EnableStencil( bool bEnable )
{
m_ShadowState.depthStencil.StencilEnable = bEnable;
}
void CShaderShadowDx11::StencilFunc( ShaderStencilFunc_t stencilFunc )
{
m_ShadowState.depthStencil.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)stencilFunc;
}
void CShaderShadowDx11::StencilPassOp( ShaderStencilOp_t stencilOp )
{
m_ShadowState.depthStencil.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)stencilOp;
}
void CShaderShadowDx11::StencilFailOp( ShaderStencilOp_t stencilOp )
{
m_ShadowState.depthStencil.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)stencilOp;
}
void CShaderShadowDx11::StencilDepthFailOp( ShaderStencilOp_t stencilOp )
{
m_ShadowState.depthStencil.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)stencilOp;
}
void CShaderShadowDx11::StencilReference( int nReference )
{
m_ShadowState.depthStencil.StencilRef = nReference;
}
void CShaderShadowDx11::StencilMask( int nMask )
{
m_ShadowState.depthStencil.StencilWriteMask = nMask;
}
void CShaderShadowDx11::StencilWriteMask( int nMask )
{
m_ShadowState.depthStencil.StencilReadMask = nMask;
}
void CShaderShadowDx11::BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor )
{
//m_ShadowState.colorBlendAttrib.bIndependentAlphaBlend = true;
m_ShadowState.blend.RenderTarget[0].SrcBlendAlpha = TranslateD3D11BlendFunc( srcFactor );
m_ShadowState.blend.RenderTarget[0].DestBlendAlpha = TranslateD3D11BlendFunc( dstFactor );
}
// Alpha to coverage
void CShaderShadowDx11::EnableAlphaToCoverage( bool bEnable )
{
m_ShadowState.blend.AlphaToCoverageEnable = bEnable ? TRUE : FALSE;
}
void CShaderShadowDx11::FogMode( ShaderFogMode_t fogMode )
{
m_ShadowState.fogMode = fogMode;
}
StateSnapshot_t CShaderShadowDx11::FindOrCreateSnapshot()
{
StatesDx11::ShadowState lookup;
lookup.desc = m_ShadowState;
int i = m_ShadowStates.Find( lookup );
if ( i != m_ShadowStates.InvalidIndex() )
{
return i;
}
// Didn't find it, add entry
lookup.m_iBlendState = FindOrCreateBlendState( lookup.desc.blend );
lookup.m_iDepthStencilState = FindOrCreateDepthStencilState( lookup.desc.depthStencil );
lookup.m_iRasterState = FindOrCreateRasterState( lookup.desc.rasterizer );
lookup.m_iVSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.vsConstantBuffers );
lookup.m_iGSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.gsConstantBuffers );
lookup.m_iPSConstantBufferState = FindOrCreateConstantBufferState( lookup.desc.psConstantBuffers );
StateSnapshot_t snap = m_ShadowStates.AddToTail( lookup );
return snap;
}
const StatesDx11::ShadowState *CShaderShadowDx11::GetShadowState( StateSnapshot_t id )
{
if ( id == DEFAULT_SHADOW_STATE_ID )
return GetDefaultShadowState();
return &m_ShadowStates.Element( id );
}
const StatesDx11::ShadowState *CShaderShadowDx11::GetDefaultShadowState()
{
if ( !m_DefaultShadowState.desc.blend.m_pD3DState )
{
// Needed to wait until this was called to create the D3D state objects because
// D3D is not initialized when the constructor of this class is called.
m_DefaultDepthStencilState.SetDefault();
unsigned int iDefaultDS = FindOrCreateDepthStencilState( m_DefaultDepthStencilState );
m_DefaultShadowState.desc.depthStencil = m_DefaultDepthStencilState;
m_DefaultShadowState.m_iDepthStencilState = iDefaultDS;
m_DefaultRasterState.SetDefault();
unsigned int iDefaultRS = FindOrCreateRasterState( m_DefaultRasterState );
m_DefaultShadowState.desc.rasterizer = m_DefaultRasterState;
m_DefaultShadowState.m_iRasterState = iDefaultRS;
m_DefaultBlendState.SetDefault();
unsigned int iDefaultBS = FindOrCreateBlendState( m_DefaultBlendState );
m_DefaultShadowState.desc.blend = m_DefaultBlendState;
m_DefaultShadowState.m_iBlendState = iDefaultBS;
}
return &m_DefaultShadowState;
}
// Constant buffer setting
void CShaderShadowDx11::SetVertexShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer )
{
m_ShadowState.vsConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer();
if ( slot > m_ShadowState.vsConstantBuffers.m_MaxSlot )
{
m_ShadowState.vsConstantBuffers.m_MaxSlot = slot;
}
}
void CShaderShadowDx11::SetVertexShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer )
{
SetVertexShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) );
}
void CShaderShadowDx11::SetGeometryShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer )
{
m_ShadowState.gsConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer();
if ( slot > m_ShadowState.gsConstantBuffers.m_MaxSlot )
{
m_ShadowState.gsConstantBuffers.m_MaxSlot = slot;
}
}
void CShaderShadowDx11::SetGeometryShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer )
{
SetGeometryShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) );
}
void CShaderShadowDx11::SetPixelShaderConstantBuffer( int slot, ConstantBufferHandle_t cbuffer )
{
m_ShadowState.psConstantBuffers.m_ppBuffers[slot] = ( (CShaderConstantBufferDx11 *)cbuffer )->GetD3DBuffer();
if ( slot > m_ShadowState.psConstantBuffers.m_MaxSlot )
{
m_ShadowState.psConstantBuffers.m_MaxSlot = slot;
}
}
void CShaderShadowDx11::SetPixelShaderConstantBuffer( int slot, ShaderInternalConstantBuffer_t cbuffer )
{
SetPixelShaderConstantBuffer( slot, g_pShaderAPIDx11->GetInternalConstantBuffer( cbuffer ) );
}
unsigned int CShaderShadowDx11::FindOrCreateConstantBufferState( StatesDx11::ConstantBufferDesc &desc )
{
int i = m_ConstantBufferStates.Find( desc );
if ( m_ConstantBufferStates.IsValidIndex( i ) )
{
return i;
}
// Make a new state
return m_ConstantBufferStates.AddToTail( desc );
}
unsigned int CShaderShadowDx11::FindOrCreateDepthStencilState( StatesDx11::DepthStencilDesc &desc )
{
int i = m_DepthStencilStates.Find( desc );
if ( m_DepthStencilStates.IsValidIndex( i ) )
{
desc.m_pD3DState = m_DepthStencilStates[i].m_pD3DState;
return i;
}
D3D11Device()->CreateDepthStencilState( &desc, &desc.m_pD3DState );
Assert( SUCCEEDED( hr ) );
i = m_DepthStencilStates.AddToTail( desc );
return i;
}
unsigned int CShaderShadowDx11::FindOrCreateBlendState( StatesDx11::BlendDesc &desc )
{
int i = m_BlendStates.Find( desc );
if ( m_BlendStates.IsValidIndex( i ) )
{
desc.m_pD3DState = m_BlendStates[i].m_pD3DState;
return i;
}
D3D11Device()->CreateBlendState( &desc, &desc.m_pD3DState );
Assert( SUCCEEDED( hr ) );
i = m_BlendStates.AddToTail( desc );
return i;
}
unsigned int CShaderShadowDx11::FindOrCreateRasterState( StatesDx11::RasterDesc &desc )
{
int i = m_RasterizerStates.Find( desc );
if ( m_RasterizerStates.IsValidIndex( i ) )
{
desc.m_pD3DState = m_RasterizerStates[i].m_pD3DState;
return i;
}
D3D11Device()->CreateRasterizerState( &desc, &desc.m_pD3DState );
Assert( SUCCEEDED( hr ) );
i = m_RasterizerStates.AddToTail( desc );
return i;
}
// ---------------------------------------------------
// Below are unsupported by Dx11, only included to
// not break compatibility with Dx9.
// ---------------------------------------------------
// A simpler method of dealing with alpha modulation
void CShaderShadowDx11::EnableAlphaPipe( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableAlphaPipe() called\n" );
}
void CShaderShadowDx11::EnableConstantAlpha( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableConstantAlpha() called\n" );
}
void CShaderShadowDx11::EnableVertexAlpha( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableVertexAlpha() called\n" );
}
void CShaderShadowDx11::EnableTextureAlpha( TextureStage_t stage, bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableTextureAlpha() called\n" );
}
void CShaderShadowDx11::SetShadowDepthFiltering( Sampler_t stage )
{
//Warning( "Unsupported CShaderShadowDx11::SetShadowDepthFiltering() called\n" );
}
void CShaderShadowDx11::EnableCustomPixelPipe( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableCustomPixelPipe() called\n" );
}
void CShaderShadowDx11::CustomTextureStages( int stageCount )
{
//Warning( "Unsupported CShaderShadowDx11::CustomTextureStages() called\n" );
}
void CShaderShadowDx11::CustomTextureOperation( TextureStage_t stage, ShaderTexChannel_t channel,
ShaderTexOp_t op, ShaderTexArg_t arg1, ShaderTexArg_t arg2 )
{
//Warning( "Unsupported CShaderShadowDx11::CustomTextureOperation() called\n" );
}
void CShaderShadowDx11::EnableSRGBWrite( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableSRGBWrite() called\n" );
}
void CShaderShadowDx11::EnableSRGBRead( Sampler_t stage, bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableSRGBRead() called\n" );
}
void CShaderShadowDx11::SetDiffuseMaterialSource( ShaderMaterialSource_t materialSource )
{
//Warning( "Unsupported CShaderShadowDx11::SetDiffuseMaterialSource() called\n" );
}
void CShaderShadowDx11::EnableTexGen( TextureStage_t stage, bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableTexGen() called\n" );
}
void CShaderShadowDx11::TexGen( TextureStage_t stage, ShaderTexGenParam_t param )
{
//Warning( "Unsupported CShaderShadowDx11::TexGen() called\n" );
}
// per texture unit stuff
void CShaderShadowDx11::OverbrightValue( TextureStage_t stage, float value )
{
//Warning( "Unsupported CShaderShadowDx11::OverbrightValue() called\n" );
}
void CShaderShadowDx11::DisableFogGammaCorrection( bool bDisable )
{
m_ShadowState.disableFogGammaCorrection = bDisable;
}
void CShaderShadowDx11::EnableSpecular( bool bEnable )
{
//Warning( "Unsupported CShaderShadowDx11::EnableSpecular() called!\n" );
}
// indicates what per-vertex data we're providing
void CShaderShadowDx11::DrawFlags( unsigned int drawFlags )
{
//Warning( "Unsupported CShaderShadowDx11::DrawFlags() called!\n" );
}
void CShaderShadowDx11::BlendOp(ShaderBlendOp_t blendOp)
{
//Warning( "Unsupported CShaderShadowDx11::BlendOp() called!\n" );
}
void CShaderShadowDx11::BlendOpSeparateAlpha(ShaderBlendOp_t blendOp)
{
//Warning( "Unsupported CShaderShadowDx11::BlendOpSeparateAlpha() called!\n" );
}