/* * Copyright 2019-2021 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * In no event and under no legal theory, whether in tort (including negligence), * contract, or otherwise, unless required by applicable law (such as deliberate * and grossly negligent acts) or agreed to in writing, shall any Contributor be * liable for any damages, including any direct, indirect, special, incidental, * or consequential damages of any character arising as a result of this License or * out of the use or inability to use the software (including but not limited to damages * for loss of goodwill, work stoppage, computer failure or malfunction, or any and * all other commercial damages or losses), even if such Contributor has been advised * of the possibility of such damages. */ #pragma once /// \file /// Definition of the Diligent::IShader interface and related data structures #include "../../../Primitives/interface/FileStream.h" #include "../../../Primitives/interface/FlagEnum.h" #include "DeviceObject.h" DILIGENT_BEGIN_NAMESPACE(Diligent) // {2989B45C-143D-4886-B89C-C3271C2DCC5D} static const INTERFACE_ID IID_Shader = {0x2989b45c, 0x143d, 0x4886, {0xb8, 0x9c, 0xc3, 0x27, 0x1c, 0x2d, 0xcc, 0x5d}}; // clang-format off /// Describes the shader type DILIGENT_TYPED_ENUM(SHADER_TYPE, Uint32) { SHADER_TYPE_UNKNOWN = 0x0000, ///< Unknown shader type SHADER_TYPE_VERTEX = 0x0001, ///< Vertex shader SHADER_TYPE_PIXEL = 0x0002, ///< Pixel (fragment) shader SHADER_TYPE_GEOMETRY = 0x0004, ///< Geometry shader SHADER_TYPE_HULL = 0x0008, ///< Hull (tessellation control) shader SHADER_TYPE_DOMAIN = 0x0010, ///< Domain (tessellation evaluation) shader SHADER_TYPE_COMPUTE = 0x0020, ///< Compute shader SHADER_TYPE_AMPLIFICATION = 0x0040, ///< Amplification (task) shader SHADER_TYPE_MESH = 0x0080, ///< Mesh shader SHADER_TYPE_RAY_GEN = 0x0100, ///< Ray generation shader SHADER_TYPE_RAY_MISS = 0x0200, ///< Ray miss shader SHADER_TYPE_RAY_CLOSEST_HIT = 0x0400, ///< Ray closest hit shader SHADER_TYPE_RAY_ANY_HIT = 0x0800, ///< Ray any hit shader SHADER_TYPE_RAY_INTERSECTION = 0x1000, ///< Ray intersection shader SHADER_TYPE_CALLABLE = 0x2000, ///< Callable shader SHADER_TYPE_LAST = SHADER_TYPE_CALLABLE, /// All graphics pipeline shader stages SHADER_TYPE_ALL_GRAPHICS = SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL | SHADER_TYPE_GEOMETRY | SHADER_TYPE_HULL | SHADER_TYPE_DOMAIN, /// All mesh shading pipeline stages SHADER_TYPE_ALL_MESH = SHADER_TYPE_AMPLIFICATION | SHADER_TYPE_MESH | SHADER_TYPE_PIXEL, /// All ray-tracing pipeline shader stages SHADER_TYPE_ALL_RAY_TRACING = SHADER_TYPE_RAY_GEN | SHADER_TYPE_RAY_MISS | SHADER_TYPE_RAY_CLOSEST_HIT | SHADER_TYPE_RAY_ANY_HIT | SHADER_TYPE_RAY_INTERSECTION | SHADER_TYPE_CALLABLE }; DEFINE_FLAG_ENUM_OPERATORS(SHADER_TYPE); /// Describes the shader source code language DILIGENT_TYPED_ENUM(SHADER_SOURCE_LANGUAGE, Uint32) { /// Default language (GLSL for OpenGL/OpenGLES/Vulkan devices, HLSL for Direct3D11/Direct3D12 devices) SHADER_SOURCE_LANGUAGE_DEFAULT = 0, /// The source language is HLSL SHADER_SOURCE_LANGUAGE_HLSL, /// The source language is GLSL SHADER_SOURCE_LANGUAGE_GLSL, /// The source language is Metal shading language (MSL) SHADER_SOURCE_LANGUAGE_MSL, /// The source language is GLSL that should be compiled verbatim /// By default the engine prepends GLSL shader source code with platform-specific /// definitions. For instance it adds appropriate #version directive (e.g. '#version 430 core' or /// '#version 310 es') so that the same source will work on different versions of desktop OpenGL and OpenGLES. /// When SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM is used, the source code will be compiled as is. /// Note that shader macros are ignored when compiling GLSL verbatim in OpenGL backend, and an application /// should add the macro definitions to the source code. SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM }; /// Describes the shader compiler that will be used to compile the shader source code DILIGENT_TYPED_ENUM(SHADER_COMPILER, Uint32) { /// Default compiler for specific language and API that is selected as follows: /// - Direct3D11: legacy HLSL compiler (FXC) /// - Direct3D12: legacy HLSL compiler (FXC) /// - OpenGL(ES) GLSL: native compiler /// - OpenGL(ES) HLSL: HLSL2GLSL converter and native compiler /// - Vulkan GLSL: built-in glslang /// - Vulkan HLSL: built-in glslang (with limitted support for Shader Model 6.x) SHADER_COMPILER_DEFAULT = 0, /// Built-in glslang compiler for GLSL and HLSL. SHADER_COMPILER_GLSLANG, /// Modern HLSL compiler (DXC) for Direct3D12 and Vulkan with Shader Model 6.x support. SHADER_COMPILER_DXC, /// Legacy HLSL compiler (FXC) for Direct3D11 and Direct3D12 supporting shader models up to 5.1. SHADER_COMPILER_FXC, SHADER_COMPILER_LAST = SHADER_COMPILER_FXC }; /// Describes the flags that can be passed over to IShaderSourceInputStreamFactory::CreateInputStream2() function. DILIGENT_TYPED_ENUM(CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS, Uint32) { /// No flag. CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_NONE = 0x00, /// Do not output any messages if the file is not found or /// other errors occur. CREATE_SHADER_SOURCE_INPUT_STREAM_FLAG_SILENT = 0x01, }; DEFINE_FLAG_ENUM_OPERATORS(CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS); /// Shader description struct ShaderDesc DILIGENT_DERIVE(DeviceObjectAttribs) /// Shader type. See Diligent::SHADER_TYPE. SHADER_TYPE ShaderType DEFAULT_INITIALIZER(SHADER_TYPE_UNKNOWN); }; typedef struct ShaderDesc ShaderDesc; // clang-format on // {3EA98781-082F-4413-8C30-B9BA6D82DBB7} static const INTERFACE_ID IID_IShaderSourceInputStreamFactory = {0x3ea98781, 0x82f, 0x4413, {0x8c, 0x30, 0xb9, 0xba, 0x6d, 0x82, 0xdb, 0xb7}}; // clang-format off #define DILIGENT_INTERFACE_NAME IShaderSourceInputStreamFactory #include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" #define IShaderSourceInputStreamFactoryInclusiveMethods \ IObjectInclusiveMethods; \ IShaderSourceInputStreamFactoryMethods ShaderSourceInputStreamFactory /// Shader source stream factory interface DILIGENT_BEGIN_INTERFACE(IShaderSourceInputStreamFactory, IObject) { VIRTUAL void METHOD(CreateInputStream)(THIS_ const Char* Name, IFileStream** ppStream) PURE; VIRTUAL void METHOD(CreateInputStream2)(THIS_ const Char* Name, CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS Flags, IFileStream** ppStream) PURE; }; DILIGENT_END_INTERFACE #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE // clang-format on # define IShaderSourceInputStreamFactory_CreateInputStream(This, ...) CALL_IFACE_METHOD(ShaderSourceInputStreamFactory, CreateInputStream, This, __VA_ARGS__) # define IShaderSourceInputStreamFactory_CreateInputStream2(This, ...) CALL_IFACE_METHOD(ShaderSourceInputStreamFactory, CreateInputStream2, This, __VA_ARGS__) #endif struct ShaderMacro { const Char* Name DEFAULT_INITIALIZER(nullptr); const Char* Definition DEFAULT_INITIALIZER(nullptr); #if DILIGENT_CPP_INTERFACE ShaderMacro() noexcept {} ShaderMacro(const Char* _Name, const Char* _Def) noexcept : Name{_Name}, Definition{_Def} {} #endif }; typedef struct ShaderMacro ShaderMacro; /// Shader version struct ShaderVersion { /// Major revision Uint8 Major DEFAULT_INITIALIZER(0); /// Minor revision Uint8 Minor DEFAULT_INITIALIZER(0); #if DILIGENT_CPP_INTERFACE ShaderVersion() noexcept {} ShaderVersion(Uint8 _Major, Uint8 _Minor) noexcept : Major{_Major}, Minor{_Minor} {} bool operator==(const ShaderVersion& rhs) const { return Major == rhs.Major && Minor == rhs.Minor; } #endif }; typedef struct ShaderVersion ShaderVersion; // clang-format off /// Shader compilation flags DILIGENT_TYPED_ENUM(SHADER_COMPILE_FLAGS, Uint32) { /// No flags. SHADER_COMPILE_FLAG_NONE = 0x0, /// Enable unbounded resource arrays (e.g. Texture2D g_Texture[]). SHADER_COMPILE_FLAG_ENABLE_UNBOUNDED_ARRAYS = 0x01, /// Enable inline ray tracing for graphics and compute shaders. /// Requires RayTracing2 device feature. SHADER_COMPILE_FLAG_ENABLE_INLINE_RAY_TRACING = 0x02, SHADER_COMPILE_FLAG_LAST = SHADER_COMPILE_FLAG_ENABLE_UNBOUNDED_ARRAYS }; DEFINE_FLAG_ENUM_OPERATORS(SHADER_COMPILE_FLAGS); // clang-format on /// Shader creation attributes struct ShaderCreateInfo { /// Source file path /// If source file path is provided, Source and ByteCode members must be null const Char* FilePath DEFAULT_INITIALIZER(nullptr); /// Pointer to the shader source input stream factory. /// The factory is used to load the shader source file if FilePath is not null. /// It is also used to create additional input streams for shader include files IShaderSourceInputStreamFactory* pShaderSourceStreamFactory DEFAULT_INITIALIZER(nullptr); /// HLSL->GLSL conversion stream /// If HLSL->GLSL converter is used to convert HLSL shader source to /// GLSL, this member can provide pointer to the conversion stream. It is useful /// when the same file is used to create a number of different shaders. If /// ppConversionStream is null, the converter will parse the same file /// every time new shader is converted. If ppConversionStream is not null, /// the converter will write pointer to the conversion stream to *ppConversionStream /// the first time and will use it in all subsequent times. /// For all subsequent conversions, FilePath member must be the same, or /// new stream will be crated and warning message will be displayed. struct IHLSL2GLSLConversionStream** ppConversionStream DEFAULT_INITIALIZER(nullptr); /// Shader source /// If shader source is provided, FilePath and ByteCode members must be null const Char* Source DEFAULT_INITIALIZER(nullptr); /// Compiled shader bytecode. /// If shader byte code is provided, FilePath and Source members must be null /// \note. This option is supported for D3D11, D3D12 and Vulkan backends. /// For D3D11 and D3D12 backends, HLSL bytecode should be provided. Vulkan /// backend expects SPIRV bytecode. /// The bytecode must contain reflection information. If shaders were compiled /// using fxc, make sure that /Qstrip_reflect option is *not* specified. /// HLSL shaders need to be compiled against 4.0 profile or higher. const void* ByteCode DEFAULT_INITIALIZER(nullptr); /// Size of the compiled shader bytecode /// Byte code size (in bytes) must be provided if ByteCode is not null size_t ByteCodeSize DEFAULT_INITIALIZER(0); /// Shader entry point /// This member is ignored if ByteCode is not null const Char* EntryPoint DEFAULT_INITIALIZER("main"); /// Shader macros /// This member is ignored if ByteCode is not null const ShaderMacro* Macros DEFAULT_INITIALIZER(nullptr); /// If set to true, textures will be combined with texture samplers. /// The CombinedSamplerSuffix member defines the suffix added to the texture variable /// name to get corresponding sampler name. When using combined samplers, /// the sampler assigned to the shader resource view is automatically set when /// the view is bound. Otherwise samplers need to be explicitly set similar to other /// shader variables. /// This member has no effect if the shader is used in the PSO that uses pipeline resource signature(s). bool UseCombinedTextureSamplers DEFAULT_INITIALIZER(false); /// If UseCombinedTextureSamplers is true, defines the suffix added to the /// texture variable name to get corresponding sampler name. For example, /// for default value "_sampler", a texture named "tex" will be combined /// with sampler named "tex_sampler". /// If UseCombinedTextureSamplers is false, this member is ignored. /// This member has no effect if the shader is used in the PSO that uses pipeline resource signature(s). const Char* CombinedSamplerSuffix DEFAULT_INITIALIZER("_sampler"); /// Shader description. See Diligent::ShaderDesc. ShaderDesc Desc; /// Shader source language. See Diligent::SHADER_SOURCE_LANGUAGE. SHADER_SOURCE_LANGUAGE SourceLanguage DEFAULT_INITIALIZER(SHADER_SOURCE_LANGUAGE_DEFAULT); /// Shader compiler. See Diligent::SHADER_COMPILER. SHADER_COMPILER ShaderCompiler DEFAULT_INITIALIZER(SHADER_COMPILER_DEFAULT); /// HLSL shader model to use when compiling the shader. When default value /// is given (0, 0), the engine will attempt to use the highest HLSL shader model /// supported by the device. If the shader is created from the byte code, this value /// has no effect. /// /// \note When HLSL source is converted to GLSL, corresponding GLSL/GLESSL version will be used. ShaderVersion HLSLVersion DEFAULT_INITIALIZER({}); /// GLSL version to use when creating the shader. When default value /// is given (0, 0), the engine will attempt to use the highest GLSL version /// supported by the device. ShaderVersion GLSLVersion DEFAULT_INITIALIZER({}); /// GLES shading language version to use when creating the shader. When default value /// is given (0, 0), the engine will attempt to use the highest GLESSL version /// supported by the device. ShaderVersion GLESSLVersion DEFAULT_INITIALIZER({}); /// Shader compile flags (see Diligent::SHADER_COMPILE_FLAGS). SHADER_COMPILE_FLAGS CompileFlags DEFAULT_INITIALIZER(SHADER_COMPILE_FLAG_NONE); /// Memory address where pointer to the compiler messages data blob will be written /// The buffer contains two null-terminated strings. The first one is the compiler /// output message. The second one is the full shader source code including definitions added /// by the engine. Data blob object must be released by the client. IDataBlob** ppCompilerOutput DEFAULT_INITIALIZER(nullptr); }; typedef struct ShaderCreateInfo ShaderCreateInfo; // clang-format off /// Describes shader resource type DILIGENT_TYPED_ENUM(SHADER_RESOURCE_TYPE, Uint8) { /// Shader resource type is unknown SHADER_RESOURCE_TYPE_UNKNOWN = 0, /// Constant (uniform) buffer SHADER_RESOURCE_TYPE_CONSTANT_BUFFER, /// Shader resource view of a texture (sampled image) SHADER_RESOURCE_TYPE_TEXTURE_SRV, /// Shader resource view of a buffer (read-only storage image) SHADER_RESOURCE_TYPE_BUFFER_SRV, /// Unordered access view of a texture (sotrage image) SHADER_RESOURCE_TYPE_TEXTURE_UAV, /// Unordered access view of a buffer (storage buffer) SHADER_RESOURCE_TYPE_BUFFER_UAV, /// Sampler (separate sampler) SHADER_RESOURCE_TYPE_SAMPLER, /// Input attachment in a render pass SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT, /// Acceleration structure SHADER_RESOURCE_TYPE_ACCEL_STRUCT, SHADER_RESOURCE_TYPE_LAST = SHADER_RESOURCE_TYPE_ACCEL_STRUCT }; // clang-format on /// Shader resource description struct ShaderResourceDesc { #if DILIGENT_CPP_INTERFACE ShaderResourceDesc() noexcept {} ShaderResourceDesc(const char* _Name, SHADER_RESOURCE_TYPE _Type, Uint32 _ArraySize) noexcept : Name{_Name}, Type{_Type}, ArraySize{_ArraySize} {} #endif // clang-format off /// Shader resource name const char* Name DEFAULT_INITIALIZER(nullptr); /// Shader resource type, see Diligent::SHADER_RESOURCE_TYPE. SHADER_RESOURCE_TYPE Type DEFAULT_INITIALIZER(SHADER_RESOURCE_TYPE_UNKNOWN); /// Array size. For non-array resource this value is 1. Uint32 ArraySize DEFAULT_INITIALIZER(0); // clang-format on }; typedef struct ShaderResourceDesc ShaderResourceDesc; #define DILIGENT_INTERFACE_NAME IShader #include "../../../Primitives/interface/DefineInterfaceHelperMacros.h" #define IShaderInclusiveMethods \ IDeviceObjectInclusiveMethods; \ IShaderMethods Shader // clang-format off /// Shader interface DILIGENT_BEGIN_INTERFACE(IShader, IDeviceObject) { #if DILIGENT_CPP_INTERFACE /// Returns the shader description virtual const ShaderDesc& METHOD(GetDesc)() const override = 0; #endif /// Returns the total number of shader resources VIRTUAL Uint32 METHOD(GetResourceCount)(THIS) CONST PURE; /// Returns the pointer to the array of shader resources VIRTUAL void METHOD(GetResourceDesc)(THIS_ Uint32 Index, ShaderResourceDesc REF ResourceDesc) CONST PURE; }; DILIGENT_END_INTERFACE #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h" #if DILIGENT_C_INTERFACE // clang-format off # define IShader_GetDesc(This) (const struct ShaderDesc*)IDeviceObject_GetDesc(This) # define IShader_GetResourceCount(This) CALL_IFACE_METHOD(Shader, GetResourceCount, This) # define IShader_GetResourceDesc(This, ...) CALL_IFACE_METHOD(Shader, GetResourceDesc, This, __VA_ARGS__) // clang-format on #endif DILIGENT_END_NAMESPACE // namespace Diligent