Skip to content

Commit

Permalink
Added support for EXT_fragment_shader_interlock.
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonJoker committed May 15, 2024
1 parent 073f111 commit 8732c2d
Show file tree
Hide file tree
Showing 40 changed files with 565 additions and 57 deletions.
2 changes: 2 additions & 0 deletions include/CompilerSpirV/compileSpirV.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ namespace spirv
makeSpirVExtension( v1_0, v1_3, vUnk, NV_mesh_shader );
// Enable this extension to be able to enable use derivatives in compute shader stage.
makeSpirVExtension( v1_0, v1_3, vUnk, NV_compute_shader_derivatives );
// Enable this extension to allow use of beginInvocationInterlock and endInvocationInterlock intrinsic functions.
makeSpirVExtension( v1_0, v1_3, vUnk, EXT_fragment_shader_interlock );
// Enable this extension to prevent mapping of demote instruction to discard instruction.
makeSpirVExtension( v1_0, v1_4, v1_6, EXT_demote_to_helper_invocation );
// Enable this extension if you need any of the following intrinsic functions:
Expand Down
1 change: 1 addition & 0 deletions include/GlslCommon/GlslStatementsHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace glsl
makeGlExtension( v4_2, v4_2, v4_3, ARB_explicit_uniform_location );
makeGlExtension( v4_2, v4_2, vUnk, ARB_compute_shader );
makeGlExtension( v4_2, v4_2, vUnk, NV_shader_atomic_float );
makeGlExtension( v4_2, v4_5, vUnk, ARB_fragment_shader_interlock );
makeGlExtension( v4_3, v4_3, vUnk, NV_viewport_array2 );
makeGlExtension( v4_3, v4_3, vUnk, NV_shader_atomic_fp16_vector );
makeGlExtension( v4_4, v4_4, v4_5, ARB_derivative_control );
Expand Down
4 changes: 4 additions & 0 deletions include/ShaderAST/Expr/EnumIntrinsic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,10 @@ namespace ast::expr
eReadFirstInvocation3D,
eReadFirstInvocation4D,

// Fragment Shader Interlock Functions
eBeginInvocationInterlock,
eEndInvocationInterlock,

// Boundaries,
eCount,
eInvalid = ~( 0u ),
Expand Down
10 changes: 10 additions & 0 deletions include/ShaderAST/Expr/GetIntrinsicName.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5398,6 +5398,16 @@ namespace ast::expr
result = "ReadFirstInvocation4D";
break;


// Fragment Shader Interlock Functions
case Intrinsic::eBeginInvocationInterlock:
result = "BeginInvocationInterlock";
break;

case Intrinsic::eEndInvocationInterlock:
result = "EndInvocationInterlock";
break;

default:
throw Exception{ "Unsupported Intrinsic type." };
}
Expand Down
4 changes: 4 additions & 0 deletions include/ShaderAST/Expr/Intrinsic.enum
Original file line number Diff line number Diff line change
Expand Up @@ -1371,4 +1371,8 @@ ASTIntrDecl( Intrinsic )
ASTIntrValue( type::Kind::eVec2D, ASTIntrName( readFirstInvocation, ReadFirstInvocation, 2, D ), ASTIntrParams( ASTIntrParam( type::Kind::eVec2D, value ) ) )
ASTIntrValue( type::Kind::eVec3D, ASTIntrName( readFirstInvocation, ReadFirstInvocation, 3, D ), ASTIntrParams( ASTIntrParam( type::Kind::eVec3D, value ) ) )
ASTIntrValue( type::Kind::eVec4D, ASTIntrName( readFirstInvocation, ReadFirstInvocation, 4, D ), ASTIntrParams( ASTIntrParam( type::Kind::eVec4D, value ) ) )

// Fragment Shader Interlock Functions
ASTIntrValue( type::Kind::eVoid, ASTIntrName( beginInvocationInterlock, BeginInvocationInterlock ) )
ASTIntrValue( type::Kind::eVoid, ASTIntrName( endInvocationInterlock, EndInvocationInterlock ) )
ASTIntrEnd
22 changes: 22 additions & 0 deletions include/ShaderAST/Expr/MakeIntrinsic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23427,6 +23427,28 @@ namespace ast::expr
, Intrinsic::eReadFirstInvocation4D
, std::move( value ) );
}
// Fragment Shader Interlock Functions

/**
*@return
* void
*/
inline IntrinsicCallPtr makeBeginInvocationInterlock( ExprCache & exprCache
, type::TypesCache & typesCache )
{
return exprCache.makeIntrinsicCall( typesCache.getBasicType( type::Kind::eVoid )
, Intrinsic::eBeginInvocationInterlock );
}
/**
*@return
* void
*/
inline IntrinsicCallPtr makeEndInvocationInterlock( ExprCache & exprCache
, type::TypesCache & typesCache )
{
return exprCache.makeIntrinsicCall( typesCache.getBasicType( type::Kind::eVoid )
, Intrinsic::eEndInvocationInterlock );
}
}

#endif
11 changes: 11 additions & 0 deletions include/ShaderAST/ShaderASTPrerequisites.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ namespace ast
eBackFacingTriangle = 0xFFu,
};

enum class InvocationOrdering
{
eNone = 0u,
ePixelInterlockOrdered = 1u,
ePixelInterlockUnordered = 2u,
eSampleInterlockOrdered = 3u,
eSampleInterlockUnordered = 4u,
eShadingRateInterlockOrdered = 5u,
eShadingRateInterlockUnordered = 6u,
};

enum class Builtin
{
eNone,
Expand Down
2 changes: 1 addition & 1 deletion include/ShaderAST/Stmt/StmtCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace ast::stmt
SDAST_API ElseIfPtr makeElseIf( expr::ExprPtr ctrlExpr );
SDAST_API ElsePtr makeElse();
SDAST_API ForPtr makeFor( expr::ExprPtr initExpr, expr::ExprPtr ctrlExpr, expr::ExprPtr incrExpr );
SDAST_API FragmentLayoutPtr makeFragmentLayout( type::TypePtr type, FragmentOrigin origin, FragmentCenter center );
SDAST_API FragmentLayoutPtr makeFragmentLayout( type::TypePtr type, FragmentOrigin origin, FragmentCenter center, InvocationOrdering ordering );
SDAST_API FunctionDeclPtr makeFunctionDecl( var::VariablePtr funcVar, FunctionFlag flag = {} );
SDAST_API FunctionDeclPtr makeFunctionDecl( var::VariablePtr funcVar, uint32_t flags );
SDAST_API HitAttributeVariableDeclPtr makeHitAttributeVariableDecl( var::VariablePtr variable );
Expand Down
9 changes: 8 additions & 1 deletion include/ShaderAST/Stmt/StmtFragmentLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace ast::stmt
SDAST_API FragmentLayout( StmtCache & stmtCache
, type::TypePtr type
, FragmentOrigin origin
, FragmentCenter center );
, FragmentCenter center
, InvocationOrdering ordering );

SDAST_API void accept( VisitorPtr vis )const override;

Expand All @@ -37,10 +38,16 @@ namespace ast::stmt
return m_center;
}

InvocationOrdering getOrdering()const
{
return m_ordering;
}

private:
type::TypePtr m_type;
FragmentOrigin m_origin{ FragmentOrigin::eUpperLeft };
FragmentCenter m_center{ FragmentCenter::eHalfPixel };
InvocationOrdering m_ordering{ InvocationOrdering::eNone };
};
}

Expand Down
19 changes: 14 additions & 5 deletions include/ShaderAST/Type/TypeFragmentIO.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ namespace ast::type
: public Type
{
SDAST_API FragmentInput( TypePtr type
, ast::FragmentOrigin origin
, ast::FragmentCenter center );
, FragmentOrigin origin
, FragmentCenter center
, InvocationOrdering ordering );

TypePtr getType()const
{
Expand All @@ -31,20 +32,28 @@ namespace ast::type
return m_center;
}

InvocationOrdering getOrdering()const
{
return m_ordering;
}

private:
TypePtr m_type;
FragmentOrigin m_origin;
FragmentCenter m_center;
InvocationOrdering m_ordering;
};
using FragmentInputPtr = std::shared_ptr< FragmentInput >;

inline FragmentInputPtr makeFragmentInputType( TypePtr type
, ast::FragmentOrigin origin
, ast::FragmentCenter center )
, FragmentOrigin origin
, FragmentCenter center
, InvocationOrdering ordering )
{
return std::make_shared< FragmentInput >( type
, origin
, center );
, center
, ordering );
}
}

Expand Down
11 changes: 11 additions & 0 deletions include/ShaderWriter/FragmentWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace sdw
FragmentInT( ShaderWriter & writer
, ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, ParamsT && ... params );
template< typename ... ParamsT >
explicit FragmentInT( ShaderWriter & writer
Expand Down Expand Up @@ -101,6 +102,7 @@ namespace sdw
SDW_API void implementMain( FragmentMainFuncT< VoidT, VoidT > const & function );
SDW_API void implementMain( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< VoidT, VoidT > const & function );

template< template< ast::var::Flag FlagT > typename InT
Expand All @@ -110,6 +112,7 @@ namespace sdw
, template< ast::var::Flag FlagT > typename OutT >
void implementMainT( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< InT, OutT > const & function );

template< template< ast::var::Flag FlagT > typename InT
Expand Down Expand Up @@ -148,6 +151,14 @@ namespace sdw
, uint64_t attributes
, bool enabled = true );
/**@}*/
/**
*name
* Shader Interlock declaration.
*/
/**@{*/
SDW_API void beginInvocationInterlock();
SDW_API void endInvocationInterlock();
/**@}*/
};
/**@}*/
}
Expand Down
9 changes: 7 additions & 2 deletions include/ShaderWriter/FragmentWriter.inl
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ namespace sdw
FragmentInT< DataT >::FragmentInT( ShaderWriter & writer
, ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, ParamsT && ... params )
: FragmentInT{ writer
, makeExpr( writer
, getBuilder( writer ).registerName( "fragIn"
, makeFragmentInputType( makeType( getTypesCache( writer ), std::forward< ParamsT >( params )... )
, origin
, center )
, center
, ordering )
, FlagT ) ) }
{
}
Expand All @@ -30,6 +32,7 @@ namespace sdw
: FragmentInT{ writer
, ast::FragmentOrigin::eUpperLeft
, ast::FragmentCenter::eHalfPixel
, ast::InvocationOrdering::eNone
, std::forward< ParamsT >( params )... }
{
}
Expand Down Expand Up @@ -153,16 +156,18 @@ namespace sdw
{
this->implementMainT( ast::FragmentOrigin::eUpperLeft
, ast::FragmentCenter::eHalfPixel
, ast::InvocationOrdering::eNone
, function );
}

template< template< ast::var::Flag FlagT > typename InT
, template< ast::var::Flag FlagT > typename OutT >
inline void FragmentWriter::implementMainT( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< InT, OutT > const & function )
{
this->implementMainT( FragmentInT< InT >{ *this, origin, center }
this->implementMainT( FragmentInT< InT >{ *this, origin, center, ordering }
, FragmentOutT< OutT >{ *this }
, function );
}
Expand Down
12 changes: 12 additions & 0 deletions include/ShaderWriter/GraphicsPipelineWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace sdw
SDW_API void implementEntryPoint( FragmentMainFuncT< VoidT, VoidT > const & function );
SDW_API void implementEntryPoint( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< VoidT, VoidT > const & function );

template< template< ast::var::Flag FlagT > typename InT
Expand All @@ -40,6 +41,7 @@ namespace sdw
, template< ast::var::Flag FlagT > typename OutT >
void implementEntryPointT( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< InT, OutT > const & function );

template< template< ast::var::Flag FlagT > typename InT
Expand Down Expand Up @@ -80,6 +82,16 @@ namespace sdw
, uint64_t attributes
, bool enabled = true );
/**@}*/
#pragma endregion
#pragma region Shader Interlock declaration
/**
*name
* Shader Interlock declaration.
*/
/**@{*/
SDW_API void beginInvocationInterlock();
SDW_API void endInvocationInterlock();
/**@}*/
#pragma endregion
/**@}*/
#pragma endregion
Expand Down
4 changes: 3 additions & 1 deletion include/ShaderWriter/GraphicsPipelineWriter.inl
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ namespace sdw
{
this->implementEntryPointT( ast::FragmentOrigin::eUpperLeft
, ast::FragmentCenter::eHalfPixel
, ast::InvocationOrdering::eNone
, function );
}

template< template< ast::var::Flag FlagT > typename InT
, template< ast::var::Flag FlagT > typename OutT >
inline void GraphicsPipelineWriter::implementEntryPointT( ast::FragmentOrigin origin
, ast::FragmentCenter center
, ast::InvocationOrdering ordering
, FragmentMainFuncT< InT, OutT > const & function )
{
this->implementEntryPointT( FragmentInT< InT >{ *this, origin, center }
this->implementEntryPointT( FragmentInT< InT >{ *this, origin, center, ordering }
, FragmentOutT< OutT >{ *this }
, function );
}
Expand Down
18 changes: 18 additions & 0 deletions include/ShaderWriter/Intrinsics/IntrinsicFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2766,6 +2766,24 @@ namespace sdw
SDW_API RetDVec4 readFirstInvocation( DVec4 const value );
/**@}*/
#pragma endregion
#pragma region beginInvocationInterlock
/**
*name
* beginInvocationInterlock
*/
/**@{*/
SDW_API RetVoid beginInvocationInterlock( ShaderWriter & writer );
/**@}*/
#pragma endregion
#pragma region endInvocationInterlock
/**
*name
* endInvocationInterlock
*/
/**@{*/
SDW_API RetVoid endInvocationInterlock( ShaderWriter & writer );
/**@}*/
#pragma endregion
}

#endif
3 changes: 2 additions & 1 deletion source/CompilerGlsl/GlslAdaptStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1757,7 +1757,8 @@ namespace glsl

m_current->addStmt( m_stmtCache.makeFragmentLayout( type
, fragType.getOrigin()
, fragType.getCenter() ) );
, fragType.getCenter()
, fragType.getOrdering() ) );
}

void doProcess( ast::var::VariablePtr var
Expand Down
3 changes: 2 additions & 1 deletion source/CompilerHlsl/HlslHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3150,7 +3150,8 @@ namespace hlsl
m_highFreqInputs.initialiseMainVar( var
, ast::type::makeFragmentInputType( m_highFreqInputs.paramStruct
, fragType.getOrigin()
, fragType.getCenter() )
, fragType.getCenter()
, fragType.getOrdering() )
, m_currentRoutine->paramToEntryPoint );
}

Expand Down
3 changes: 2 additions & 1 deletion source/CompilerSpirV/SpirVAdaptStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ namespace spirv
auto type = fragType.getType();
m_current->addStmt( m_stmtCache.makeFragmentLayout( type
, fragType.getOrigin()
, fragType.getCenter() ) );
, fragType.getCenter()
, fragType.getOrdering() ) );
}

void doProcess( ast::type::GeometryOutput const & geomType )
Expand Down
17 changes: 17 additions & 0 deletions source/CompilerSpirV/SpirVFillConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,23 @@ namespace spirv

void visitFragmentLayoutStmt( ast::stmt::FragmentLayout const * stmt )override
{
switch ( stmt->getOrdering() )
{
case ast::InvocationOrdering::ePixelInterlockOrdered:
case ast::InvocationOrdering::ePixelInterlockUnordered:
m_result.registerCapability( spv::CapabilityFragmentShaderPixelInterlockEXT );
break;
case ast::InvocationOrdering::eSampleInterlockOrdered:
case ast::InvocationOrdering::eSampleInterlockUnordered:
m_result.registerCapability( spv::CapabilityFragmentShaderSampleInterlockEXT );
break;
case ast::InvocationOrdering::eShadingRateInterlockOrdered:
case ast::InvocationOrdering::eShadingRateInterlockUnordered:
m_result.registerCapability( spv::CapabilityFragmentShaderShadingRateInterlockEXT );
break;
default:
break;
}
}

void visitFunctionDeclStmt( ast::stmt::FunctionDecl const * stmt )override
Expand Down
Loading

0 comments on commit 8732c2d

Please sign in to comment.