// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/BaseTypes.h"
#include "Engine/Core/Types/String.h"
#include "Config.h"
class GPUShader;
///
/// The shader program metadata container. Contains description about resources used by the shader.
///
struct FLAXENGINE_API ShaderBindings
{
uint32 InstructionsCount;
uint32 UsedCBsMask;
uint32 UsedSRsMask;
uint32 UsedUAsMask;
bool IsUsingCB(uint32 slotIndex) const
{
return (UsedCBsMask & (1u << slotIndex)) != 0u;
}
bool IsUsingSR(uint32 slotIndex) const
{
return (UsedSRsMask & (1u << slotIndex)) != 0u;
}
bool IsUsingUA(uint32 slotIndex) const
{
return (UsedUAsMask & (1u << slotIndex)) != 0u;
}
};
struct GPUShaderProgramInitializer
{
StringAnsi Name;
ShaderBindings Bindings;
ShaderFlags Flags;
#if !BUILD_RELEASE
GPUShader* Owner;
#endif
};
///
/// Mini program that can run on the GPU.
///
class FLAXENGINE_API GPUShaderProgram
{
protected:
StringAnsi _name;
ShaderBindings _bindings;
ShaderFlags _flags;
#if !BUILD_RELEASE
GPUShader* _owner;
#endif
void Init(const GPUShaderProgramInitializer& initializer)
{
_name = initializer.Name;
_bindings = initializer.Bindings;
_flags = initializer.Flags;
#if !BUILD_RELEASE
_owner = initializer.Owner;
#endif
}
public:
///
/// Finalizes an instance of the class.
///
virtual ~GPUShaderProgram()
{
}
public:
///
/// Gets name of the shader program.
///
FORCE_INLINE const StringAnsi& GetName() const
{
return _name;
}
///
/// Gets the shader resource bindings.
///
FORCE_INLINE const ShaderBindings& GetBindings() const
{
return _bindings;
}
///
/// Gets the shader flags.
///
FORCE_INLINE ShaderFlags GetFlags() const
{
return _flags;
}
public:
///
/// Gets shader program stage type.
///
virtual ShaderStage GetStage() const = 0;
///
/// Gets buffer handle (platform dependent).
///
virtual void* GetBufferHandle() const = 0;
///
/// Gets buffer size (in bytes).
///
virtual uint32 GetBufferSize() const = 0;
};
///
/// Vertex Shader program.
///
class GPUShaderProgramVS : public GPUShaderProgram
{
public:
// Input element run-time data (see VertexShaderMeta::InputElement for compile-time data)
PACK_STRUCT(struct InputElement
{
byte Type; // VertexShaderMeta::InputType
byte Index;
byte Format; // PixelFormat
byte InputSlot;
uint32 AlignedByteOffset; // Fixed value or INPUT_LAYOUT_ELEMENT_ALIGN if auto
byte InputSlotClass; // INPUT_LAYOUT_ELEMENT_PER_VERTEX_DATA or INPUT_LAYOUT_ELEMENT_PER_INSTANCE_DATA
uint32 InstanceDataStepRate; // 0 if per-vertex
});
public:
///
/// Gets input layout description handle (platform dependent).
///
virtual void* GetInputLayout() const = 0;
///
/// Gets input layout description size (in bytes).
///
virtual byte GetInputLayoutSize() const = 0;
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Vertex;
}
};
///
/// Geometry Shader program.
///
class GPUShaderProgramGS : public GPUShaderProgram
{
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Geometry;
}
};
///
/// Hull Shader program.
///
class GPUShaderProgramHS : public GPUShaderProgram
{
protected:
int32 _controlPointsCount;
public:
///
/// Gets the input control points count (valid range: 1-32).
///
FORCE_INLINE int32 GetControlPointsCount() const
{
return _controlPointsCount;
}
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Hull;
}
};
///
/// Domain Shader program.
///
class GPUShaderProgramDS : public GPUShaderProgram
{
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Domain;
}
};
///
/// Pixel Shader program.
///
class GPUShaderProgramPS : public GPUShaderProgram
{
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Pixel;
}
};
///
/// Compute Shader program.
///
class GPUShaderProgramCS : public GPUShaderProgram
{
public:
// [GPUShaderProgram]
ShaderStage GetStage() const override
{
return ShaderStage::Compute;
}
};