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 
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 
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:
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:
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 }
Render device interface.
Definition: RenderDevice.h:55
virtual void SetArray(IDeviceObject *const *ppObjects, Uint32 FirstElement, Uint32 NumElements) override final
Sets the variable array.
Definition: ShaderBase.h:158
Base interface for all objects created by the render device Diligent::IRenderDevice.
Definition: DeviceObject.h:40
Shader resource variable.
Definition: Shader.h:265
const StaticSamplerDesc * StaticSamplers
Array of static sampler descriptions.
Definition: Shader.h:175
Shader description.
Definition: Shader.h:152
SHADER_TYPE
Describes the shader type.
Definition: Shader.h:46
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Pixel (fragment) shader.
Definition: Shader.h:50
Static sampler description.
Definition: Shader.h:136
Template class implementing base functionality for a shader object.
Definition: ShaderBase.h:172
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:46
Hull (tessellation control) shader.
Definition: Shader.h:52
Domain (tessellation evaluation) shader.
Definition: Shader.h:53
std::vector< ShaderVariableDesc, STDAllocatorRawMem< ShaderVariableDesc > > m_VariablesDesc
Shader variable descriptions.
Definition: ShaderBase.h:231
Implementation of a dummy shader variable that silently ignores all operations.
Definition: ShaderBase.h:146
Describes shader variable.
Definition: Shader.h:121
SHADER_VARIABLE_TYPE
Describes shader variable type that is used by ShaderVariableDesc.
Definition: Shader.h:100
Vertex shader.
Definition: Shader.h:49
Unknown shader type.
Definition: Shader.h:48
ShaderDesc m_Desc
Object description.
Definition: DeviceObjectBase.h:138
ShaderBase(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const ShaderDesc &ShdrDesc, bool bIsDeviceInternal=false)
Definition: ShaderBase.h:182
std::vector< StaticSamplerDesc, STDAllocatorRawMem< StaticSamplerDesc > > m_StaticSamplers
Static sampler descriptions.
Definition: ShaderBase.h:235
const ShaderVariableDesc * VariableDesc
Array of shader variable descriptions.
Definition: Shader.h:166
Base implementation of a shader variable.
Definition: ShaderBase.h:98
Template class implementing base functionality for a device object.
Definition: DeviceObjectBase.h:42
Uint32 NumVariables
Number of elements in VariableDesc array.
Definition: Shader.h:169
virtual void Set(IDeviceObject *pObject) override final
Sets the variable to the given value.
Definition: ShaderBase.h:152
DummyShaderVariable m_DummyShaderVar
Dummy shader variable.
Definition: ShaderBase.h:228
Compute shader.
Definition: Shader.h:54
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
Uint32 NumStaticSamplers
Number of static samplers in StaticSamplers array.
Definition: Shader.h:172
Geometry shader.
Definition: Shader.h:51