shader compilation configuration structure

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

shader compilation configuration structure

Post by Mel »

This snippet is rough, a beta, is unfinished, and currently, with the states of things on my side, i hardly will finish it any time soon, but, it is useful, though i haven't tested it with Geometry shaders.

It is a system, in which the shader compilation is done using a struct to store all the options when it comes to compile a shader. The compilation of a shader has many parameters, and some of the can become very long. The ideal thing is to have a structure which
can be easily initialized to store the information needed, and pass this structure to the video driver to create the shaders, and this is it.

It is tested, and it works, though it isn't heavily tested to check that everything works properly, and it isn't completely failsafe, but, makes life easier when it comes to use the shaders.

I want to leave this here so, if people gets minimally interested, it evolves to a fully working compile configuration tool for the shaders.

I have unified the vertex and pixel shader level to a single variable, because i think it is best to leave it that way. I don't know if it makes much sense to have a VS level 2 with a P/FS level 3 or the like, but if all are at the same level, it is sure there won't be any trouble

Code: Select all

 
 
enum ETARGETSHADERLEVEL
{
    ETSL_PS1 = 1,//pixelShader 1
    ETSL_PS2,//pixelShader 2
    ETSL_PS3,//pixelShader 3
    ETSL_PS4,//pixelShader 4
    ETSL_PS5,//pixelShader 5
    ETSL_COUNT = 0x7FFFFFFF //32 bit force
};
 
struct ShaderCompileInfo
{
    bool FromFile;
    bool HighLevel;
    bool IsGeometryShader;
    bool IsCG;
    core::stringc VertexShader;
    core::stringc PixelShader;
    core::stringc GeometryShader;
    core::stringc VertexEntryPoint;
    core::stringc PixelEntryPoint;
    core::stringc GeometryEntryPoint;
    s32 UserData;
    video::IShaderConstantSetCallBack* Constants;
    video::E_MATERIAL_TYPE BaseRenderStates;
    ETARGETSHADERLEVEL TargetLevel;
    scene::E_PRIMITIVE_TYPE GeometryInputPrimitive;
    scene::E_PRIMITIVE_TYPE GeometryOutputPrimitive;
    u32 MaximumVerticesCreated;
 
    bool checkCompileInfo()//this small function validates the info from this structure.
    {
        bool retVal = true;
 
        //At least, this is mandatory to be not null.
        retVal &= VertexShader.size()>0;
        retVal &= PixelShader.size()>0;
        retVal &= BaseRenderStates >= video::EMT_SOLID;
 
        if(HighLevel)//if this is highLevel, it must have an entry point.
        {
            retVal &= VertexEntryPoint.size()>0;
            retVal &= PixelEntryPoint.size()>0;
        }
 
        if(IsGeometryShader)//Geometry shaders need code and entry point.
        {
            retVal &= GeometryShader.size()>0;
            retVal &= GeometryEntryPoint.size()>0;
        }
 
        //I guess CG shaders have more options, but i don't have support for CG languaje enabled in my Irrlicht lib...
        //Geometry shaders should have extra check options, but at the time, i am not aware of them.
 
        return retVal;
    }
};
 
video::E_MATERIAL_TYPE compileCustomShaderMaterial(video::IVideoDriver* drv,struct ShaderCompileInfo& info)
{
    video::E_VERTEX_SHADER_TYPE vertexshaderLevel;
    video::E_PIXEL_SHADER_TYPE pixelshaderLevel;
    video::E_GEOMETRY_SHADER_TYPE geometryshaderLevel = video::EGST_GS_4_0;//modify this if needed!
    s32 result = -1;
 
    //We compile the shader with the info stored in the shaderCompileInfo structure
 
    if(info.checkCompileInfo())
    {
        if(drv)
        {
            switch(info.TargetLevel)
            {
                case ETSL_PS1:
                    pixelshaderLevel = video::EPST_PS_1_4;
                    vertexshaderLevel = video::EVST_VS_1_1;
                    break;
                case ETSL_PS2:
                    pixelshaderLevel = video::EPST_PS_2_0;
                    vertexshaderLevel = video::EVST_VS_2_0;
                    break;
                case ETSL_PS3:
                    pixelshaderLevel = video::EPST_PS_3_0;
                    vertexshaderLevel = video::EVST_VS_3_0;
                    break;
                case ETSL_PS4:
                    pixelshaderLevel = video::EPST_PS_4_0;
                    vertexshaderLevel = video::EVST_VS_4_0;
                    break;
                case ETSL_PS5:
                    pixelshaderLevel = video::EPST_PS_5_0;
                    vertexshaderLevel = video::EVST_VS_5_0;
                    break;
                default:
                    pixelshaderLevel = video::EPST_PS_2_0;//modify if needed
                    vertexshaderLevel = video::EVST_VS_2_0;
                break;
            }
 
            if(info.IsGeometryShader)//is it a geometry shader?
            {
                if(info.HighLevel)//Is a highlevel shader?
                {
                    if(info.FromFile)//Is from files?
                    {
                        result = drv->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
                            info.VertexShader,
                            info.VertexEntryPoint.c_str(),
                            vertexshaderLevel,
                            info.PixelShader,
                            info.PixelEntryPoint.c_str(),
                            pixelshaderLevel,
                            info.GeometryShader,
                            info.GeometryEntryPoint.c_str(),
                            geometryshaderLevel,
                            info.GeometryInputPrimitive,
                            info.GeometryOutputPrimitive,
                            info.MaximumVerticesCreated,
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                    else//The code of the shader is stored on memory
                    {
                        result = drv->getGPUProgrammingServices()->addHighLevelShaderMaterial(
                            info.VertexShader.c_str(),
                            info.VertexEntryPoint.c_str(),
                            vertexshaderLevel,
                            info.PixelShader.c_str(),
                            info.PixelEntryPoint.c_str(),
                            pixelshaderLevel,
                            info.GeometryShader.c_str(),
                            info.GeometryEntryPoint.c_str(),
                            geometryshaderLevel,
                            info.GeometryInputPrimitive,
                            info.GeometryOutputPrimitive,
                            info.MaximumVerticesCreated,
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                }//No low level Geometry shader? *shrugs*
            }
            else//No geometry shader...
            {
                if(info.HighLevel)//Is it high level?
                {
                    if(info.FromFile)//Is it from files?
                    {
                        result = drv->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
                            info.VertexShader,
                            info.VertexEntryPoint.c_str(),
                            vertexshaderLevel,
                            info.PixelShader,
                            info.PixelEntryPoint.c_str(),
                            pixelshaderLevel,
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                    else//The code is directly provided?
                    {
                        result = drv->getGPUProgrammingServices()->addHighLevelShaderMaterial(
                            info.VertexShader.c_str(),
                            info.VertexEntryPoint.c_str(),
                            vertexshaderLevel,
                            info.PixelShader.c_str(),
                            info.PixelEntryPoint.c_str(),
                            pixelshaderLevel,
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                }
                else //Low level shader
                {
                    if(info.FromFile)//Code from files?
                    {
                        result = drv->getGPUProgrammingServices()->addShaderMaterialFromFiles(
                            info.VertexShader,
                            info.PixelShader,
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                    else//code from memory?
                    {
                        result = drv->getGPUProgrammingServices()->addShaderMaterial(
                            info.VertexShader.c_str(),
                            info.PixelShader.c_str(),
                            info.Constants,
                            info.BaseRenderStates,
                            info.UserData
                            );
                    }
                }
            }
 
        }
    }
    else
    {
        cout<<"Check Failed"<<endl;
    }
 
    return (video::E_MATERIAL_TYPE) result;
//The support for CG isn't implemented.
}
 
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: shader compilation configuration structure

Post by ACE247 »

Yes, thank you! This certainly is usefull. :)
(next work item removed from my projects Todo List)
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: shader compilation configuration structure

Post by hendu »

How nice to use GL where there are no params needed, and I can just use the short functions of the form (vertex, fragment, callback) ;)

Don't mind me, that's good for DX though.
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: shader compilation configuration structure

Post by ACE247 »

It's usefull for GL too If you wan't your code to automatically compile the shader for the GPU's shaderLevel. That way we're sure we don't run PS4_0 shader on PS2_0 Hardware, and can even have it switch between more complex shaders for newer more capable hardware and simplified versions for older hardware. Okay, the code will need some expanding to accomodate that though. :)
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: shader compilation configuration structure

Post by hendu »

There are no PS2 etc levels for GL. Those parameters are ignored.
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: shader compilation configuration structure

Post by ACE247 »

Aww great... First time someone told me that. Thanks by the way.
But switching shader complexity would still be a usefull feature.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: shader compilation configuration structure

Post by Mel »

It is built over Irrlicht, not just Open GL, and the shader level is needed, so that is why it is there.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: shader compilation configuration structure

Post by hendu »

ACE247 wrote:Aww great... First time someone told me that. Thanks by the way.
But switching shader complexity would still be a usefull feature.
Your shader either compiles or it doesn't. There are no compile switches.

You can switch complexity of course, if the card doesn't report feature foo, you load a shader that doesn't use feature foo. For example the recent array textures, you can check if they are supported, and if not, send a fallback shader.
Post Reply