// Copyright (c) 2012-2023 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; } };