Diligent Engine API Reference: D:/GitHub/DiligentEngine/DiligentCore/Graphics/GraphicsEngine/include/ShaderBase.h Source File

Diligent Engine API Reference

ShaderBase.h
1 /* Copyright 2015-2018 Egor Yusov
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12 *
13 * In no event and under no legal theory, whether in tort (including negligence),
14 * contract, or otherwise, unless required by applicable law (such as deliberate
15 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16 * liable for any damages, including any direct, indirect, special, incidental,
17 * or consequential damages of any character arising as a result of this License or
18 * out of the use or inability to use the software (including but not limited to damages
19 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20 * all other commercial damages or losses), even if such Contributor has been advised
21 * of the possibility of such damages.
22 */
23
24 #pragma once
25
28
29 #include "Shader.h"
30 #include "DeviceObjectBase.h"
31 #include "STDAllocator.h"
32 #include "PlatformMisc.h"
33 #include "EngineMemory.h"
34
35 namespace Diligent
36 {
37
38 inline SHADER_TYPE GetShaderTypeFromIndex( Int32 Index )
39 {
40 return static_cast<SHADER_TYPE>(1 << Index);
41 }
42
43 inline Int32 GetShaderTypeIndex( SHADER_TYPE Type )
44 {
45 Int32 ShaderIndex = PlatformMisc::GetLSB(Type);
46
47 #ifdef _DEBUG
48 switch( Type )
49 {
50 case SHADER_TYPE_UNKNOWN: VERIFY_EXPR(ShaderIndex == -1); break;
51 case SHADER_TYPE_VERTEX: VERIFY_EXPR(ShaderIndex == 0); break;
52 case SHADER_TYPE_PIXEL: VERIFY_EXPR(ShaderIndex == 1); break;
53 case SHADER_TYPE_GEOMETRY:VERIFY_EXPR(ShaderIndex == 2); break;
54 case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderIndex == 3); break;
55 case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderIndex == 4); break;
56 case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderIndex == 5); break;
57 default: UNEXPECTED( "Unexpected shader type (", Type, ")" ); break;
58 }
59 VERIFY( Type == GetShaderTypeFromIndex(ShaderIndex), "Incorrect shader type index" );
60 #endif
61 return ShaderIndex;
62 }
63
64 static const int VSInd = GetShaderTypeIndex(SHADER_TYPE_VERTEX);
65 static const int PSInd = GetShaderTypeIndex(SHADER_TYPE_PIXEL);
66 static const int GSInd = GetShaderTypeIndex(SHADER_TYPE_GEOMETRY);
67 static const int HSInd = GetShaderTypeIndex(SHADER_TYPE_HULL);
68 static const int DSInd = GetShaderTypeIndex(SHADER_TYPE_DOMAIN);
69 static const int CSInd = GetShaderTypeIndex(SHADER_TYPE_COMPUTE);
70
71 template<typename TNameCompare>
72 SHADER_VARIABLE_TYPE GetShaderVariableType(SHADER_VARIABLE_TYPE DefaultVariableType, const ShaderVariableDesc *VariableDesc, Uint32 NumVars, TNameCompare NameCompare)
73 {
74 for (Uint32 v = 0; v < NumVars; ++v)
75 {
76 const auto &CurrVarDesc = VariableDesc[v];
77 if ( NameCompare(CurrVarDesc.Name) )
78 {
79 return CurrVarDesc.Type;
80 }
81 }
82 return DefaultVariableType;
83 }
84
85 inline SHADER_VARIABLE_TYPE GetShaderVariableType(const Char* Name, SHADER_VARIABLE_TYPE DefaultVariableType, const ShaderVariableDesc *VariableDesc, Uint32 NumVars)
86 {
87 return GetShaderVariableType(DefaultVariableType, VariableDesc, NumVars,
88 [&](const char *VarName)
89 {
90 return strcmp(VarName, Name) == 0;
91 }
92 );
93 }
94
95
97
98 struct ShaderVariableBase : public IShaderVariable
99 {
100 ShaderVariableBase(IObject &Owner) :
101 // Shader variables are always created as part of the shader, or
102 // shader resource binding, so we must provide owner pointer to
103 // the base class constructor
104 m_Owner(Owner)
105 {
106 }
107
108 IObject& GetOwner()
109 {
110 return m_Owner;
111 }
112
113 virtual IReferenceCounters* GetReferenceCounters()const override final
114 {
115 return m_Owner.GetReferenceCounters();
116 }
117
118 virtual Atomics::Long AddRef()override final
119 {
120 return m_Owner.AddRef();
121 }
122
123 virtual Atomics::Long Release()override final
124 {
125 return m_Owner.Release();
126 }
127
128 virtual void QueryInterface( const INTERFACE_ID &IID, IObject **ppInterface )override final
129 {
130 if( ppInterface == nullptr )
131 return;
132
133 *ppInterface = nullptr;
134 if( IID == IID_ShaderVariable || IID == IID_Unknown )
135 {
136 *ppInterface = this;
137 (*ppInterface)->AddRef();
138 }
139 }
140
141 protected:
142 IObject &m_Owner;
143 };
144
146 struct DummyShaderVariable : ShaderVariableBase
147 {
148 DummyShaderVariable(IObject &Owner) :
149 ShaderVariableBase(Owner)
150 {}
151
152 virtual void Set( IDeviceObject *pObject )override final
153 {
154 // Ignore operation
155 // Probably output warning
156 }
157
158 virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements)override final
159 {
160 // Ignore operation
161 // Probably output warning
162 }
163 };
164
166
171 template<class BaseInterface, class RenderDeviceBaseInterface>
172 class ShaderBase : public DeviceObjectBase<BaseInterface, ShaderDesc>
173 {
174 public:
175 typedef DeviceObjectBase<BaseInterface, ShaderDesc> TDeviceObjectBase;
176
182 ShaderBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const ShaderDesc& ShdrDesc, bool bIsDeviceInternal = false ) :
183 TDeviceObjectBase( pRefCounters, pDevice, ShdrDesc, bIsDeviceInternal ),
184 m_DummyShaderVar(*this),
185 m_VariablesDesc(ShdrDesc.NumVariables, ShaderVariableDesc(), STD_ALLOCATOR_RAW_MEM(ShaderVariableDesc, GetRawAllocator(), "Allocator for vector<ShaderVariableDesc>") ),
186 m_StringPool(ShdrDesc.NumVariables + ShdrDesc.NumStaticSamplers, String(), STD_ALLOCATOR_RAW_MEM(String, GetRawAllocator(), "Allocator for vector<String>")),
187 m_StaticSamplers(ShdrDesc.NumStaticSamplers, StaticSamplerDesc(), STD_ALLOCATOR_RAW_MEM(StaticSamplerDesc, GetRawAllocator(), "Allocator for vector<StaticSamplerDesc>") )
188 {
189 auto Str = m_StringPool.begin();
190 if(this->m_Desc.VariableDesc)
191 {
192 for (Uint32 v = 0; v < this->m_Desc.NumVariables; ++v, ++Str)
193 {
194 m_VariablesDesc[v] = this->m_Desc.VariableDesc[v];
195 VERIFY(m_VariablesDesc[v].Name != nullptr, "Variable name not provided");
196 *Str = m_VariablesDesc[v].Name;
197 m_VariablesDesc[v].Name = Str->c_str();
198 }
199 this->m_Desc.VariableDesc = m_VariablesDesc.data();
200 }
201 if(this->m_Desc.StaticSamplers)
202 {
203 for (Uint32 s = 0; s < this->m_Desc.NumStaticSamplers; ++s, ++Str)
204 {
205 m_StaticSamplers[s] = this->m_Desc.StaticSamplers[s];
206 VERIFY(m_StaticSamplers[s].TextureName != nullptr, "Static sampler texture name not provided");
207 *Str = m_StaticSamplers[s].TextureName;
208 m_StaticSamplers[s].TextureName = Str->c_str();
209 #ifdef _DEBUG
210 const auto &BorderColor = m_StaticSamplers[s].Desc.BorderColor;
211 if( !( (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 0) ||
212 (BorderColor[0] == 0 && BorderColor[1] == 0 && BorderColor[2] == 0 && BorderColor[3] == 1) ||
213 (BorderColor[0] == 1 && BorderColor[1] == 1 && BorderColor[2] == 1 && BorderColor[3] == 0) ) )
214 {
215 LOG_WARNING_MESSAGE("Static sampler for variable \"", *Str , "\" specifies border color (", BorderColor[0], ", ", BorderColor[1], ", ", BorderColor[2], ", ", BorderColor[3], "). D3D12 static samplers only allow transparent black (0,0,0,1), opaque black (0,0,0,0) or opaque white (1,1,1,0) as border colors");
216 }
217 #endif
218 }
219 this->m_Desc.StaticSamplers = m_StaticSamplers.data();
220 }
221
222 VERIFY_EXPR(Str == m_StringPool.end());
223 }
224
225 IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_Shader, TDeviceObjectBase )
226
227 protected:
228 DummyShaderVariable m_DummyShaderVar;
229
231 std::vector<ShaderVariableDesc, STDAllocatorRawMem<ShaderVariableDesc> > m_VariablesDesc;
233 std::vector<String, STDAllocatorRawMem<String> > m_StringPool;
235 std::vector<StaticSamplerDesc, STDAllocatorRawMem<StaticSamplerDesc> > m_StaticSamplers;
236 };
237
238 }
Diligent::IRenderDevice
Render device interface.
Definition: RenderDevice.h:55
Diligent::DummyShaderVariable::SetArray
virtual void SetArray(IDeviceObject *const *ppObjects, Uint32 FirstElement, Uint32 NumElements) override final
Sets the variable array.
Definition: ShaderBase.h:158
Diligent::IDeviceObject
Base interface for all objects created by the render device Diligent::IRenderDevice.
Definition: DeviceObject.h:40
Diligent::IShaderVariable
Shader resource variable.
Definition: Shader.h:265
Diligent::ShaderDesc::StaticSamplers
const StaticSamplerDesc * StaticSamplers
Array of static sampler descriptions.
Definition: Shader.h:175
Diligent::ShaderDesc
Shader description.
Definition: Shader.h:152
Diligent::SHADER_TYPE
SHADER_TYPE
Describes the shader type.
Definition: Shader.h:46
Diligent
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Diligent::SHADER_TYPE_PIXEL
Pixel (fragment) shader.
Definition: Shader.h:50
Diligent::StaticSamplerDesc
Static sampler description.
Definition: Shader.h:136
Diligent::ShaderBase
Template class implementing base functionality for a shader object.
Definition: ShaderBase.h:172
Diligent::GetRawAllocator
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:46
Diligent::SHADER_TYPE_HULL
Hull (tessellation control) shader.
Definition: Shader.h:52
Diligent::SHADER_TYPE_DOMAIN
Domain (tessellation evaluation) shader.
Definition: Shader.h:53
Diligent::ShaderBase::m_VariablesDesc
std::vector< ShaderVariableDesc, STDAllocatorRawMem< ShaderVariableDesc > > m_VariablesDesc
Shader variable descriptions.
Definition: ShaderBase.h:231
Diligent::DummyShaderVariable
Implementation of a dummy shader variable that silently ignores all operations.
Definition: ShaderBase.h:146
Diligent::ShaderVariableDesc
Describes shader variable.
Definition: Shader.h:121
Diligent::SHADER_VARIABLE_TYPE
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
Diligent::SHADER_TYPE_VERTEX
Vertex shader.
Definition: Shader.h:49
Diligent::SHADER_TYPE_UNKNOWN
Unknown shader type.
Definition: Shader.h:48
Diligent::DeviceObjectBase< BaseInterface, ShaderDesc >::m_Desc
ShaderDesc m_Desc
Object description.
Definition: DeviceObjectBase.h:138
Diligent::ShaderBase::ShaderBase
ShaderBase(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const ShaderDesc &ShdrDesc, bool bIsDeviceInternal=false)
Definition: ShaderBase.h:182
Diligent::ShaderBase::m_StaticSamplers
std::vector< StaticSamplerDesc, STDAllocatorRawMem< StaticSamplerDesc > > m_StaticSamplers
Static sampler descriptions.
Definition: ShaderBase.h:235
Diligent::ShaderDesc::VariableDesc
const ShaderVariableDesc * VariableDesc
Array of shader variable descriptions.
Definition: Shader.h:166
Diligent::ShaderVariableBase
Base implementation of a shader variable.
Definition: ShaderBase.h:98
Diligent::DeviceObjectBase
Template class implementing base functionality for a device object.
Definition: DeviceObjectBase.h:42
Diligent::ShaderDesc::NumVariables
Uint32 NumVariables
Number of elements in VariableDesc array.
Definition: Shader.h:169
Diligent::DummyShaderVariable::Set
virtual void Set(IDeviceObject *pObject) override final
Sets the variable to the given value.
Definition: ShaderBase.h:152
Diligent::ShaderBase::m_DummyShaderVar
DummyShaderVariable m_DummyShaderVar
Dummy shader variable.
Definition: ShaderBase.h:228
Diligent::SHADER_TYPE_COMPUTE
Compute shader.
Definition: Shader.h:54
Diligent::ShaderBase::m_StringPool
std::vector< String, STDAllocatorRawMem< String > > m_StringPool
String pool that is used to hold copies of variable names and static sampler names.
Definition: ShaderBase.h:233
Diligent::ShaderDesc::NumStaticSamplers
Uint32 NumStaticSamplers
Number of static samplers in StaticSamplers array.
Definition: Shader.h:172
Diligent::SHADER_TYPE_GEOMETRY
Geometry shader.
Definition: Shader.h:51