Effect.h#

Parent directory (pfx)

A pvr::assets::Effect is the description of the entire rendering setup and can be used to create objects and use them for rendering.

Includes#

  • PVRCore/stream/Stream.h

  • PVRCore/strings/StringHash.h

  • PVRCore/texture/Texture.h

  • PVRCore/types/GpuDataTypes.h

  • PVRCore/types/Types.h

  • set (AndroidAssetStream.h)

Included By#

Namespaces#

Classes#

Enums#

Typedefs#

Source Code#

#pragma once
#include "PVRCore/texture/Texture.h"
#include "PVRCore/types/GpuDataTypes.h"
#include "PVRCore/types/Types.h"
#include "PVRCore/stream/Stream.h"
#include "PVRCore/strings/StringHash.h"
#include <set>

namespace pvr {
enum class VariableScope
{
    Unknown,
    Automatic,
    Model,
    Effect,
    Node,
    BoneBatch,
};

namespace effect {
template<typename MyType_>
class NameComparable
{
public:
    StringHash name;
    NameComparable() {}
    NameComparable(StringHash&& name) : name(std::move(name)) {}
    NameComparable(const StringHash& name) : name(name) {}

    typedef MyType_ MyType;
    bool operator<(const MyType& rhs) const { return name < rhs.name; }
    bool operator>(const MyType& rhs) const { return name > rhs.name; }

    bool operator>=(const MyType& rhs) const { return name >= rhs.name; }
    bool operator<=(const MyType& rhs) const { return name <= rhs.name; }

    bool operator==(const MyType& rhs) const { return name == rhs.name; }
    bool operator!=(const MyType& rhs) const { return name != rhs.name; }
};

struct TextureDefinition : public NameComparable<TextureDefinition>
{
    StringHash path;
    uint32_t width;
    uint32_t height;
    ImageDataFormat format;
    TextureDefinition() {}
    TextureDefinition(const StringHash& name, const StringHash& path, uint32_t width, uint32_t height, const ImageDataFormat& format)
        : NameComparable(name), path(path), width(width), height(height), format(format)
    {}

    bool isFile() { return path.empty(); }
};

struct TextureRef
{
    StringHash textureName;
    uint8_t set;
    uint8_t binding;
    StringHash variableName;

    TextureRef() {}

    TextureRef(StringHash textureName, uint8_t set, uint8_t binding, StringHash variableName) : textureName(textureName), set(set), binding(binding), variableName(variableName) {}
};

struct TextureReference : public TextureRef
{
    PackedSamplerFilter samplerFilter;
    SamplerAddressMode wrapS;
    SamplerAddressMode wrapT;
    SamplerAddressMode wrapR;
    StringHash semantic;
};

struct Shader : public NameComparable<Shader>
{
    std::string source;
    ShaderType type;
    Shader() {}
    Shader(StringHash&& name, ShaderType type, std::string&& source) : NameComparable<Shader>(std::move(name)), source(std::move(source)), type(type) {}
};
typedef const Shader* ShaderReference;

struct BufferDefinition : public NameComparable<BufferDefinition>
{
    struct Entry
    {
        StringHash semantic;
        GpuDatatypes dataType;
        uint32_t arrayElements;
    };
    BufferUsageFlags allSupportedBindings;
    bool isDynamic;
    std::vector<Entry> entries;
    VariableScope scope;
    bool multibuffering;
    BufferDefinition() : allSupportedBindings(BufferUsageFlags(0)), isDynamic(false), scope(VariableScope::Effect), multibuffering(0) {}
};

struct DescriptorRef
{
    int8_t set;
    int8_t binding;
    DescriptorRef() : set(0), binding(0) {}
};

struct BufferRef : DescriptorRef
{
    StringHash semantic;
    StringHash bufferName;
    DescriptorType type;
};

struct UniformSemantic : DescriptorRef
{
    StringHash semantic;
    StringHash variableName;
    GpuDatatypes dataType;
    uint32_t arrayElements;
    VariableScope scope;
};

struct AttributeSemantic
{
    StringHash semantic;
    StringHash variableName;
    GpuDatatypes dataType;
    uint8_t location;
    uint8_t vboBinding;
};

struct InputAttachmentRef : DescriptorRef
{
    int8_t targetIndex;
    InputAttachmentRef() : targetIndex(-1) {}
};

struct PipelineVertexBinding
{
    uint32_t index;
    StepRate stepRate;

    PipelineVertexBinding() : stepRate(StepRate::Vertex) {}

    PipelineVertexBinding(uint32_t index, StepRate stepRate) : index(index), stepRate(stepRate) {}
};

struct PipelineDefinition : public NameComparable<PipelineDefinition>
{
    std::vector<ShaderReference> shaders;
    std::vector<UniformSemantic> uniforms;
    std::vector<AttributeSemantic> attributes;
    std::vector<TextureReference> textures;
    std::vector<BufferRef> buffers;
    BlendingConfig blending;
    std::vector<InputAttachmentRef> inputAttachments;
    std::vector<PipelineVertexBinding> vertexBinding;
    // depth states
    bool enableDepthTest;
    bool enableDepthWrite;
    CompareOp depthCmpFunc;

    // stencil states
    bool enableStencilTest;
    StencilState stencilFront;
    StencilState stencilBack;

    // rasterization states
    PolygonWindingOrder windingOrder;
    Face cullFace;

    PipelineDefinition()
        : enableDepthTest(false), enableDepthWrite(true), depthCmpFunc(CompareOp::Less), enableStencilTest(false), windingOrder(PolygonWindingOrder::FrontFaceCCW), cullFace(Face::None)
    {}
};

struct PipelineCondition
{
    enum ConditionType
    {
        Always,
        UniformRequired,
        AttributeRequired,
        UniformRequiredNo,
        AttributeRequiredNo,
        AdditionalExport,
    } type;
    StringHash value;
};

struct PipelineReference
{
    StringHash pipelineName;
    std::vector<PipelineCondition> conditions;
    std::vector<StringHash> identifiers;
};

struct SubpassGroup
{
    StringHash name;
    std::vector<PipelineReference> pipelines;
};

struct Subpass
{
    enum
    {
        MaxTargets = 4,
        MaxInputs = 4
    };
    StringHash targets[MaxTargets];
    StringHash inputs[MaxInputs];
    bool useDepthStencil;
    std::vector<SubpassGroup> groups;
};

struct Pass
{
    StringHash name;
    StringHash targetDepthStencil;
    std::vector<Subpass> subpasses;
};

struct Effect
{
    using EffectHandle = std::shared_ptr<Effect>;
    using EffectReader = void (*)(const ::pvr::Stream& stream, Effect& thisEffect);
    static EffectHandle createWithReader(EffectReader reader, const ::pvr::Stream& stream)
    {
        EffectHandle handle = std::make_shared<Effect>();
        reader(stream, *handle);
        return handle;
    }

    void loadWithReader(EffectReader reader, const ::pvr::Stream& stream) { reader(stream, *this); }

    StringHash name;
    std::map<StringHash, std::string> headerAttributes;

    std::map<StringHash, std::map<StringHash, Shader>> versionedShaders;
    std::map<StringHash, std::map<StringHash, PipelineDefinition>> versionedPipelines;

    std::map<StringHash, TextureDefinition> textures;
    std::map<StringHash, BufferDefinition> buffers;

    std::vector<Pass> passes;
    mutable std::vector<StringHash> versions;

    const std::vector<StringHash>& getVersions() const
    {
        if (versions.empty())
        {
            for(auto it = versionedPipelines.begin(); it != versionedPipelines.end(); ++it) { versions.emplace_back(it->first); }
        }
        return versions;
    }

    void addVersion(const StringHash& apiName)
    {
        versionedShaders[apiName];
        versionedPipelines[apiName];
    }

    void addShader(const StringHash& apiName, Shader&& shader) { versionedShaders[apiName][shader.name] = std::move(shader); }
    void addShader(const StringHash& apiName, const Shader& shader) { versionedShaders[apiName][shader.name] = shader; }

    void addTexture(TextureDefinition&& texture) { textures[texture.name] = std::move(texture); }
    void addTexture(const TextureDefinition& texture) { textures[texture.name] = texture; }

    void addBuffer(BufferDefinition&& buffer) { buffers[buffer.name] = std::move(buffer); }

    void addBuffer(const BufferDefinition& buffer) { buffers[buffer.name] = buffer; }

    void addPipeline(const StringHash& apiName, PipelineDefinition&& pipeline)
    {
        versionedPipelines[apiName][pipeline.name] = std::move(pipeline);
        versions.clear();
    }

    void addPipeline(const StringHash& apiName, const PipelineDefinition& pipeline)
    {
        versionedPipelines[apiName][pipeline.name] = pipeline;
        versions.clear();
    }

    void clear()
    {
        name.clear();
        headerAttributes.clear();
        passes.clear();
        textures.clear();
        buffers.clear();
        versionedPipelines.clear();
        versionedShaders.clear();
    }
};

} // namespace effect
typedef effect::Effect Effect;
} // namespace pvr