// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "GPUShaderProgram.h" #include "Engine/Graphics/GPUResource.h" #include "Engine/Core/Collections/Dictionary.h" class GPUConstantBuffer; class GPUShaderProgram; /// /// The runtime version of the shaders cache supported by the all graphics back-ends. The same for all the shader cache formats (easier to sync and validate). /// #define GPU_SHADER_CACHE_VERSION 9 /// /// Represents collection of shader programs with permutations and custom names. /// class GPUShaderProgramsContainer { private: Dictionary _shaders; public: /// /// Initializes a new instance of the class. /// GPUShaderProgramsContainer(); /// /// Finalizes an instance of the class. /// ~GPUShaderProgramsContainer(); public: /// /// Adds a new shader program to the collection. /// /// The shader to store. /// The shader permutation index. void Add(GPUShaderProgram* shader, int32 permutationIndex); /// /// Gets a shader of given name and permutation index. /// /// The shader program name. /// The shader permutation index. /// Stored shader program or null if cannot find it. GPUShaderProgram* Get(const StringAnsiView& name, int32 permutationIndex) const; /// /// Clears collection (deletes all shaders). /// void Clear(); public: /// /// Calculates unique hash for given shader program name and its permutation index. /// /// The shader program name. /// The shader program permutation index. /// Calculated hash value. static uint32 CalculateHash(const StringAnsiView& name, int32 permutationIndex); }; /// /// The GPU resource with shader programs that can run on the GPU and are able to perform rendering calculation using textures, vertices and other resources. /// API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUShader : public GPUResource { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUShader); protected: GPUShaderProgramsContainer _shaders; GPUConstantBuffer* _constantBuffers[MAX_CONSTANT_BUFFER_SLOTS]; GPUShader(); public: /// /// Creates the shader resource and loads its data from the bytes. /// The stream with compiled shader data. /// True if cannot create state, otherwise false. virtual bool Create(class MemoryReadStream& stream); public: /// /// Gets the vertex shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramVS* GetVS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Vertex, name, permutationIndex)); } /// /// Gets the hull shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramHS* GetHS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Hull, name, permutationIndex)); } /// /// Gets domain shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramDS* GetDS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Domain, name, permutationIndex)); } /// /// Gets the geometry shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramGS* GetGS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Geometry, name, permutationIndex)); } /// /// Gets the pixel shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramPS* GetPS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Pixel, name, permutationIndex)); } /// /// Gets the compute shader. /// /// The shader program name. /// The shader permutation index. /// The shader object. API_FUNCTION() FORCE_INLINE GPUShaderProgramCS* GetCS(const StringAnsiView& name, int32 permutationIndex = 0) const { return static_cast(GetShader(ShaderStage::Compute, name, permutationIndex)); } /// /// Gets the constant buffer. /// /// The buffer slot index. /// The Constant Buffer object. API_FUNCTION() FORCE_INLINE GPUConstantBuffer* GetCB(int32 slot) const { ASSERT_LOW_LAYER(slot >= 0 && slot < ARRAY_COUNT(_constantBuffers)); return _constantBuffers[slot]; } public: /// /// Determines whether the specified shader program is in the shader. /// /// The shader program name. /// The shader permutation index. /// true if the shader is valid; otherwise, false. FORCE_INLINE bool HasShader(const StringAnsiView& name, int32 permutationIndex = 0) const { return _shaders.Get(name, permutationIndex) != nullptr; } protected: GPUShaderProgram* GetShader(ShaderStage stage, const StringAnsiView& name, int32 permutationIndex) const; virtual GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, byte* cacheBytes, uint32 cacheSize, MemoryReadStream& stream) = 0; public: // [GPUResource] GPUResourceType GetResourceType() const final override; protected: // [GPUResource] void OnReleaseGPU() override; };