Parser - Sampler definition instruction
This commit is contained in:
parent
7e5b69e714
commit
46972c7e60
4 changed files with 356 additions and 12 deletions
21
demo.srd
21
demo.srd
|
@ -80,23 +80,21 @@
|
|||
|
||||
(fn dof-init ()
|
||||
# Sampler used for the inputs
|
||||
{ NOT IMPLEMENTED
|
||||
(sampler dof-sampler
|
||||
(mipmaps no)
|
||||
(wrapping clamp-edge)
|
||||
(sampling linear)
|
||||
(lod 0 0)
|
||||
)
|
||||
}
|
||||
(sampler dof-sampler
|
||||
(mipmaps no)
|
||||
(wrapping clamp-edge)
|
||||
(sampling linear)
|
||||
(lod 0 0)
|
||||
)
|
||||
|
||||
# Texture & RT for pass 1
|
||||
(texture tx-dof-pass1 rgb-f16 vp-width vp-height)
|
||||
(texture tx-dof-pass1 rgb-f16 $vp-width $vp-height)
|
||||
(framebuffer rt-dof-pass1 tx-dof-pass1)
|
||||
|
||||
# Texture & RT for pass 2
|
||||
(texture tx-dof-pass2 rgb-f16 vp-width vp-height)
|
||||
(texture tx-dof-pass2 rgb-f16 $vp-width $vp-height)
|
||||
(framebuffer rt-dof-pass2 tx-dof-pass2)
|
||||
# MAYBE ? (alias tx-dof-output tx-dof-pass2)
|
||||
# TODO MAYBE ? (alias tx-dof-output tx-dof-pass2)
|
||||
|
||||
# Output debugging
|
||||
(odbg tx-dof-pass1 hdr "DoF - First pass")
|
||||
|
@ -158,7 +156,6 @@
|
|||
# Second pass
|
||||
(call dof-set-uniforms prg-dof-pass2)
|
||||
(use-texture 0 tx-dof-pass1 dof-sampler)
|
||||
|
||||
(use-pipeline pl-dof-pass2)
|
||||
(use-framebuffer rt-dof-pass2)
|
||||
(viewport 0 0 $vp-width $vp-height)
|
||||
|
|
75
opast.cc
75
opast.cc
|
@ -174,6 +174,23 @@ A_Node* opast::ASTVisitorBrowser(
|
|||
break;
|
||||
}
|
||||
|
||||
// Sampler definition may have LOD expressions
|
||||
case A_Node::OP_SAMPLER:
|
||||
{
|
||||
auto& n( (T_SamplerInstrNode&) node );
|
||||
auto c = child;
|
||||
if ( n.minLod( ) ) {
|
||||
if ( c == 0 ) {
|
||||
return n.minLod( );
|
||||
}
|
||||
c--;
|
||||
}
|
||||
if ( n.maxLod( ) && c == 0 ) {
|
||||
return n.maxLod( );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Uniforms instruction
|
||||
case A_Node::OP_UNIFORMS:
|
||||
{
|
||||
|
@ -381,3 +398,61 @@ T_OutputDebugInstrNode::T_OutputDebugInstrNode(
|
|||
description_( description.stringValue( ) ) ,
|
||||
locDescription_( description.location( ) )
|
||||
{ }
|
||||
|
||||
|
||||
/*= T_SamplerInstrNode =========================================================*/
|
||||
|
||||
T_Optional< T_SRDLocation > T_SamplerInstrNode::setSampling(
|
||||
E_TexSampling mode ,
|
||||
T_SRDLocation const& location ) noexcept
|
||||
{
|
||||
if ( sampling_ ) {
|
||||
return sampling_->location;
|
||||
}
|
||||
sampling_ = T_Sampling_{ location , mode };
|
||||
return {};
|
||||
}
|
||||
|
||||
T_Optional< T_SRDLocation > T_SamplerInstrNode::setMipmapSampling(
|
||||
E_TexSampling mode ,
|
||||
T_SRDLocation const& location ) noexcept
|
||||
{
|
||||
if ( mipmaps_ ) {
|
||||
return mipmaps_->location;
|
||||
}
|
||||
mipmaps_ = T_Mipmaps_{ location , mode };
|
||||
return {};
|
||||
}
|
||||
|
||||
T_Optional< T_SRDLocation > T_SamplerInstrNode::setNoMipmap(
|
||||
T_SRDLocation const& location ) noexcept
|
||||
{
|
||||
if ( mipmaps_ ) {
|
||||
return mipmaps_->location;
|
||||
}
|
||||
mipmaps_ = T_Mipmaps_{ location , {} };
|
||||
return {};
|
||||
}
|
||||
|
||||
T_Optional< T_SRDLocation > T_SamplerInstrNode::setWrapping(
|
||||
E_TexWrap mode ,
|
||||
T_SRDLocation const& location ) noexcept
|
||||
{
|
||||
if ( wrapping_ ) {
|
||||
return wrapping_->location;
|
||||
}
|
||||
wrapping_ = T_Wrapping_{ location , mode };
|
||||
return {};
|
||||
}
|
||||
|
||||
T_Optional< T_SRDLocation > T_SamplerInstrNode::setLOD(
|
||||
T_SRDLocation const& location ,
|
||||
P_ExpressionNode min ,
|
||||
P_ExpressionNode max ) noexcept
|
||||
{
|
||||
if ( lod_ ) {
|
||||
return lod_->location;
|
||||
}
|
||||
lod_ = T_LOD_{ location , std::move( min ) , std::move( max ) };
|
||||
return {};
|
||||
}
|
||||
|
|
84
opast.hh
84
opast.hh
|
@ -29,6 +29,7 @@ class A_Node
|
|||
OP_PIPELINE , // Shader pipeline declaration
|
||||
OP_PROFILE , // Profiling block
|
||||
OP_PROGRAM , // Shader program declaration
|
||||
OP_SAMPLER , // Define sampler
|
||||
OP_SET , // Set instruction
|
||||
OP_TEXTURE , // Define texture
|
||||
OP_UNIFORMS , // Set uniforms
|
||||
|
@ -602,6 +603,89 @@ class T_ProgramInstrNode : public A_InstructionNode
|
|||
{ return idLocation_; }
|
||||
};
|
||||
|
||||
// Sampler definition
|
||||
class T_SamplerInstrNode : public A_InstructionNode
|
||||
{
|
||||
private:
|
||||
struct T_Sampling_
|
||||
{
|
||||
T_SRDLocation location;
|
||||
E_TexSampling mode;
|
||||
};
|
||||
|
||||
struct T_Mipmaps_
|
||||
{
|
||||
T_SRDLocation location;
|
||||
T_Optional< E_TexSampling > mode;
|
||||
};
|
||||
|
||||
struct T_Wrapping_
|
||||
{
|
||||
T_SRDLocation location;
|
||||
E_TexWrap mode;
|
||||
};
|
||||
|
||||
struct T_LOD_
|
||||
{
|
||||
T_SRDLocation location;
|
||||
P_ExpressionNode min;
|
||||
P_ExpressionNode max;
|
||||
};
|
||||
|
||||
T_String id_;
|
||||
T_SRDLocation idLocation_;
|
||||
|
||||
T_Optional< T_Sampling_ > sampling_;
|
||||
T_Optional< T_Mipmaps_ > mipmaps_;
|
||||
T_Optional< T_Wrapping_ > wrapping_;
|
||||
T_Optional< T_LOD_ > lod_;
|
||||
|
||||
public:
|
||||
T_SamplerInstrNode(
|
||||
T_InstrListNode& parent ,
|
||||
T_SRDToken const& id ) noexcept
|
||||
: A_InstructionNode( OP_SAMPLER , parent ) ,
|
||||
id_( id.stringValue( ) ) ,
|
||||
idLocation_( id.location( ) )
|
||||
{ }
|
||||
|
||||
T_String const& id( ) const noexcept
|
||||
{ return id_; }
|
||||
T_SRDLocation const& idLocation( ) const noexcept
|
||||
{ return idLocation_; }
|
||||
|
||||
// Attempt to set sampling mode, mipmap mode, wrapping mode or
|
||||
// LOD minimal/maximal, returning the location of the previous
|
||||
// definition if there was one.
|
||||
T_Optional< T_SRDLocation > setSampling(
|
||||
E_TexSampling mode ,
|
||||
T_SRDLocation const& location ) noexcept;
|
||||
T_Optional< T_SRDLocation > setMipmapSampling(
|
||||
E_TexSampling mode ,
|
||||
T_SRDLocation const& location ) noexcept;
|
||||
T_Optional< T_SRDLocation > setNoMipmap(
|
||||
T_SRDLocation const& location ) noexcept;
|
||||
T_Optional< T_SRDLocation > setWrapping(
|
||||
E_TexWrap mode ,
|
||||
T_SRDLocation const& location ) noexcept;
|
||||
T_Optional< T_SRDLocation > setLOD(
|
||||
T_SRDLocation const& location ,
|
||||
P_ExpressionNode min ,
|
||||
P_ExpressionNode max ) noexcept;
|
||||
|
||||
// Get either the defined values or the defaults
|
||||
E_TexSampling sampling( ) const noexcept
|
||||
{ return sampling_ ? sampling_->mode : E_TexSampling::NEAREST; }
|
||||
T_Optional< E_TexSampling > mipmap( ) const noexcept
|
||||
{ return mipmaps_ ? mipmaps_->mode : T_Optional< E_TexSampling >{}; }
|
||||
E_TexWrap wrapping( ) const noexcept
|
||||
{ return wrapping_ ? wrapping_->mode : E_TexWrap::REPEAT; }
|
||||
A_ExpressionNode* minLod( ) const noexcept
|
||||
{ return lod_ ? lod_->min.get( ) : nullptr; }
|
||||
A_ExpressionNode* maxLod( ) const noexcept
|
||||
{ return lod_ ? lod_->max.get( ) : nullptr; }
|
||||
};
|
||||
|
||||
// Setting a global variable
|
||||
class T_SetInstrNode : public A_InstructionNode
|
||||
{
|
||||
|
|
188
opparser.cc
188
opparser.cc
|
@ -22,6 +22,7 @@ struct T_ParserImpl_
|
|||
PIPELINE ,
|
||||
PROFILE ,
|
||||
PROGRAM ,
|
||||
SAMPLER ,
|
||||
SET ,
|
||||
TEXTURE ,
|
||||
UNIFORMS_FLT ,
|
||||
|
@ -48,6 +49,7 @@ struct T_ParserImpl_
|
|||
add( "pipeline" , E_InstrType::PIPELINE );
|
||||
add( "profiling" , E_InstrType::PROFILE );
|
||||
add( "program" , E_InstrType::PROGRAM );
|
||||
add( "sampler" , E_InstrType::SAMPLER );
|
||||
add( "set" , E_InstrType::SET );
|
||||
add( "texture" , E_InstrType::TEXTURE );
|
||||
add( "uniforms" , E_InstrType::UNIFORMS_FLT );
|
||||
|
@ -193,6 +195,21 @@ struct T_ParserImpl_
|
|||
M_DPARSER_( Pipeline );
|
||||
M_DPARSER_( Profile );
|
||||
M_DPARSER_( Program );
|
||||
|
||||
M_DPARSER_( Sampler );
|
||||
void parseSamplerSampling(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input );
|
||||
void parseSamplerMipmaps(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input );
|
||||
void parseSamplerWrapping(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input );
|
||||
void parseSamplerLOD(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input );
|
||||
|
||||
M_DPARSER_( Set );
|
||||
M_DPARSER_( Texture );
|
||||
|
||||
|
@ -473,6 +490,7 @@ void T_ParserImpl_::parseInstructions(
|
|||
M_CASE_( PIPELINE , Pipeline );
|
||||
M_CASE_( PROFILE , Profile );
|
||||
M_CASE_( PROGRAM , Program );
|
||||
M_CASE_( SAMPLER , Sampler );
|
||||
M_CASE_( SET , Set );
|
||||
M_CASE_( TEXTURE , Texture );
|
||||
M_CASE_( UNIFORMS_FLT , Uniforms );
|
||||
|
@ -797,6 +815,176 @@ M_INSTR_( Program )
|
|||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
M_INSTR_( Sampler )
|
||||
{
|
||||
const auto ni{ input.size( ) };
|
||||
if ( ni == 1 || input[ 0 ].type( ) != E_SRDTokenType::WORD ) {
|
||||
errors.addNew( "sampler identifier expected" ,
|
||||
input[ ni == 1 ? 0 : 1 ].location( ) );
|
||||
return;
|
||||
}
|
||||
|
||||
auto& instr{ instructions.add< T_SamplerInstrNode >( input[ 1 ] ) };
|
||||
instr.location( ) = input[ 0 ].location( );
|
||||
|
||||
for ( auto i = 2u ; i < ni ; i ++ ) {
|
||||
T_SRDToken const& token( input[ i ] );
|
||||
if ( token.type( ) != E_SRDTokenType::LIST || token.list( ).empty( ) ) {
|
||||
errors.addNew( "list expected" , token.location( ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
T_SRDToken const& et( token.list( )[ 0 ] );
|
||||
if ( et.type( ) != E_SRDTokenType::WORD ) {
|
||||
errors.addNew( "'sampling', 'mipmaps', 'wrapping' or 'lod' expected" ,
|
||||
et.location( ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
T_String const& etn( et.stringValue( ) );
|
||||
if ( etn == "sampling" ) {
|
||||
parseSamplerSampling( instr , token.list( ) );
|
||||
} else if ( etn == "mipmaps" ) {
|
||||
parseSamplerMipmaps( instr , token.list( ) );
|
||||
} else if ( etn == "wrapping" ) {
|
||||
parseSamplerWrapping( instr , token.list( ) );
|
||||
} else if ( etn == "lod" ) {
|
||||
parseSamplerLOD( instr , token.list( ) );
|
||||
} else {
|
||||
errors.addNew( "'sampling', 'mipmaps', 'wrapping' or 'lod' expected" ,
|
||||
et.location( ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void T_ParserImpl_::parseSamplerSampling(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input )
|
||||
{
|
||||
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
|
||||
errors.addNew( "sampling mode expected" ,
|
||||
input[ input.size( ) == 1 ? 0 : 1 ].location( ) );
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
T_String const& sMode{ input[ 1 ].stringValue( ) };
|
||||
E_TexSampling smp{ E_TexSampling::NEAREST };
|
||||
if ( sMode == "linear" ) {
|
||||
smp = E_TexSampling::LINEAR;
|
||||
} else if ( sMode != "nearest" ) {
|
||||
errors.addNew( "'nearest' or 'linear' expected" , input[ 1 ].location( ) );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( input.size( ) > 2 ) {
|
||||
errors.addNew( "too many arguments" , input[ 2 ].location( ) );
|
||||
}
|
||||
|
||||
const auto prev{ instruction.setSampling( smp , input[ 0 ].location( ) ) };
|
||||
if ( prev && ok ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "sampling mode already set at " << *prev;
|
||||
errors.addNew( std::move( sb ) , input[ 0 ].location( ) );
|
||||
}
|
||||
}
|
||||
|
||||
void T_ParserImpl_::parseSamplerMipmaps(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input )
|
||||
{
|
||||
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
|
||||
errors.addNew( "mipmap sampling mode expected" ,
|
||||
input[ input.size( ) == 1 ? 0 : 1 ].location( ) );
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
T_String const& sMode{ input[ 1 ].stringValue( ) };
|
||||
T_Optional< E_TexSampling > smp{ };
|
||||
if ( sMode == "linear" ) {
|
||||
smp = E_TexSampling::LINEAR;
|
||||
} else if ( sMode == "nearest" ) {
|
||||
smp = E_TexSampling::NEAREST;
|
||||
} else if ( sMode != "no" ) {
|
||||
errors.addNew( "'no', 'nearest' or 'linear' expected" , input[ 1 ].location( ) );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( input.size( ) > 2 ) {
|
||||
errors.addNew( "too many arguments" , input[ 2 ].location( ) );
|
||||
}
|
||||
|
||||
const auto prev{ smp
|
||||
? instruction.setMipmapSampling( *smp , input[ 0 ].location( ) )
|
||||
: instruction.setNoMipmap( input[ 0 ].location( ) ) };
|
||||
if ( prev && ok ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "mipmap sampling mode already set at " << *prev;
|
||||
errors.addNew( std::move( sb ) , input[ 0 ].location( ) );
|
||||
}
|
||||
}
|
||||
|
||||
void T_ParserImpl_::parseSamplerWrapping(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input )
|
||||
{
|
||||
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
|
||||
errors.addNew( "wrapping mode expected" ,
|
||||
input[ input.size( ) == 1 ? 0 : 1 ].location( ) );
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
T_String const& sMode{ input[ 1 ].stringValue( ) };
|
||||
E_TexWrap smp{ E_TexWrap::REPEAT };
|
||||
if ( sMode == "clamp-border" ) {
|
||||
smp = E_TexWrap::CLAMP_BORDER;
|
||||
} else if ( sMode == "clamp-edge" ) {
|
||||
smp = E_TexWrap::CLAMP_EDGE;
|
||||
} else if ( sMode != "repeat" ) {
|
||||
errors.addNew( "'repeat', 'clamp-border' or 'clamp-edge' expected" ,
|
||||
input[ 1 ].location( ) );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( input.size( ) > 2 ) {
|
||||
errors.addNew( "too many arguments" , input[ 2 ].location( ) );
|
||||
}
|
||||
|
||||
const auto prev{ instruction.setWrapping( smp , input[ 0 ].location( ) ) };
|
||||
if ( prev && ok ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "wrapping mode already set at " << *prev;
|
||||
errors.addNew( std::move( sb ) , input[ 0 ].location( ) );
|
||||
}
|
||||
}
|
||||
|
||||
void T_ParserImpl_::parseSamplerLOD(
|
||||
T_SamplerInstrNode& instruction ,
|
||||
T_SRDList const& input )
|
||||
{
|
||||
if ( input.size( ) < 3 ) {
|
||||
errors.addNew( "min/max LODs expected" , input[ 0 ].location( ) );
|
||||
return;
|
||||
}
|
||||
if ( input.size( ) > 3 ) {
|
||||
errors.addNew( "too many arguments" , input[ 2 ].location( ) );
|
||||
}
|
||||
|
||||
P_ExpressionNode min{ parseExpression( instruction , input[ 1 ] ) };
|
||||
P_ExpressionNode max{ parseExpression( instruction , input[ 2 ] ) };
|
||||
const auto prev{ instruction.setLOD( input[ 0 ].location( ) ,
|
||||
std::move( min ) , std::move( max ) ) };
|
||||
if ( prev ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "min/max LOD already set at " << *prev;
|
||||
errors.addNew( std::move( sb ) , input[ 0 ].location( ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
M_INSTR_( Set )
|
||||
{
|
||||
bool ok{ true };
|
||||
|
|
Loading…
Reference in a new issue