Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ShaderProfile to allow for pipeline extensibility #4992

Merged
merged 7 commits into from
Jul 8, 2016

Conversation

tomspilman
Copy link
Member

This PR is the first baby step towards making the content pipeline more easily extendable for new platforms.

Here I refactored the existing enum ShaderProfile into a class that knows how to perform various platform specific steps of the effect compiling process.

This also introduces a helper class LoadedTypeCollection<T> which scans loaded assemblies for types of a particular base class. We use this to gather the different instances of ShaderProfile which in the future could live in different pipeline extension assemblies.

This same technique will be applied to audio and texture processing next.

@tomspilman tomspilman added this to the 3.6 Release milestone Jul 7, 2016
@tomspilman
Copy link
Member Author

@KonajuGames @dellis1972 - Let's be sure to squash merge this one.

@tomspilman
Copy link
Member Author

The unit tests for shader compiling all passed which is good. Want @dellis1972 to at least take a look at it first, but we should look to merge this soon.

@dellis1972
Copy link
Contributor

@tomspilman looks ok. Any chance you can give a basic example of how to extend for a new platform? Just for reference. i.e what files need to be added etc.

@tomspilman
Copy link
Member Author

tomspilman commented Jul 7, 2016

@dellis1972

Any chance you can give a basic example of how to extend for a new platform?

Sure. This same technique will be used for all the hardware specific conversions... shaders, textures, audio.

In the case of shaders you just need to create one new class that derives from ShaderProfile:

class NewPlatformShaderProfile : ShaderProfile
{
    public NewPlatformShaderProfile() 
        : base("PlatformName", 123)
    {
    }

    internal override void AddMacros(Dictionary<string, string> macros)
    {
        // Sometimes you want to add shader macros that
        // let the shader author make changes based on platforms.
    }

    internal override void ValidateShaderModels(PassInfo pass)
    {
        // This lets you validate that the shader model in the 
        // pass information is valid for this platform.
    }

    internal override ShaderData CreateShader(ShaderInfo shaderInfo, string shaderFunction, string shaderProfile, bool isVertexShader, EffectObject effect, ref string errorsAndWarnings)
    {
        // This actually does the compiling of the shader returning a new ShaderData.
    }

    internal override bool Supports(string platform)
    {
        if (platform == "MyPlatform")
            return true;

        return false;
    }
}

The same sort of technique will be used for texture processing:

class MyNewPlatformTextureProfile : TextureProfile
{
    public override bool Supports(TargetPlatform platform)
    {
        if (platform == TargetPlatform.MyNewPlatform)
            return true;

        return false;
    }

    public override void Requirements(ContentProcessorContext context, TextureProcessorOutputFormat format, out bool requiresPowerOfTwo, out bool requiresSquare)
    {
        // TODO: Let the caller know if the texture processed with the specified
        // texture format will require power-of-two and/or square sizing.
        //
        // This is called from texture packing code like with fonts.
    }

    protected override void PlatformCompressTexture(ContentProcessorContext context, TextureContent content, TextureProcessorOutputFormat format, bool generateMipmaps, bool sharpAlpha)
    {
        // TODO: Do the actual compression of the content based
        // on platform requirements.
    }
}

That is it... the system will pick up the new profile and query it when trying to convert textures/shaders/audio for the new platform (or platforms) it supports.

You can see how just adding a new instance of a class is a much easier extension system than having to modify TextureProcessor, GraphicsUtils, SoundEffectProcessor, etc to add a new platform. It also allows for us to eventually place platform specific content processing into its own extension assembly.

@dellis1972
Copy link
Contributor

@tomspilman thanks looks like a good change to me.
@KonajuGames shall I merge or you :P

@KonajuGames
Copy link
Contributor

Merging.

@KonajuGames KonajuGames merged commit 78e193e into MonoGame:develop Jul 8, 2016
harry-cpp pushed a commit to harry-cpp/MonoGame that referenced this pull request Jul 23, 2016
…4992)

* Refactored the ShaderProfile enum into extensible class.

* Added Enumeration<T> for easier creation of enumeration types.
Refactored shader creation into a single function call.

* Helper for deleting files without exceptions.

* Missed in previous commit.

* Added XB1 and Vita to platforms.

* Added new LoadedTypeCollection<T> helper.
Refactor ShaderProfile to not try to mimic an Enum.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants