// Copyright (c) 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 12 /// /// 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: Dictionary _shaders; GPUConstantBuffer* _constantBuffers[GPU_MAX_CB_BINDED]; 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 { #if GPU_ALLOW_TESSELLATION_SHADERS return static_cast(GetShader(ShaderStage::Hull, name, permutationIndex)); #else return nullptr; #endif } /// /// 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 { #if GPU_ALLOW_TESSELLATION_SHADERS return static_cast(GetShader(ShaderStage::Domain, name, permutationIndex)); #else return nullptr; #endif } /// /// 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 { #if GPU_ALLOW_GEOMETRY_SHADERS return static_cast(GetShader(ShaderStage::Geometry, name, permutationIndex)); #else return nullptr; #endif } /// /// 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]; } /// /// 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. bool HasShader(const StringAnsiView& name, int32 permutationIndex = 0) const; protected: GPUShaderProgram* GetShader(ShaderStage stage, const StringAnsiView& name, int32 permutationIndex) const; virtual GPUShaderProgram* CreateGPUShaderProgram(ShaderStage type, const GPUShaderProgramInitializer& initializer, Span bytecode, MemoryReadStream& stream) = 0; static void ReadVertexLayout(MemoryReadStream& stream, GPUVertexLayout*& inputLayout, GPUVertexLayout*& vertexLayout); public: // [GPUResource] GPUResourceType GetResourceType() const final override; protected: // [GPUResource] void OnReleaseGPU() override; };