4 using System.Collections.Generic;
6 using SiliconStudio.Core;
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Core.Serialization;
9 using SiliconStudio.Core.Serialization.Contents;
10 using SiliconStudio.Core.Serialization.Converters;
11 using SiliconStudio.Paradox.Effects;
12 using SiliconStudio.Paradox.Graphics.Internals;
13 using SiliconStudio.Paradox.Shaders;
14 using SiliconStudio.Paradox.Shaders.Compiler;
16 namespace SiliconStudio.
Paradox.Graphics
18 [ContentSerializer(typeof(DataContentConverterSerializer<Effect>))]
22 private EffectProgram program;
24 private EffectParameterResourceBinding[] resourceBindings;
29 private const int DefaultParameterCollectionCount = 3;
31 private EffectStateBindings effectStateBindings;
42 ConverterContext.RegisterConverter(
new EffectConverter());
68 if (device == null)
throw new ArgumentNullException(
"device");
69 if (bytecode == null)
throw new ArgumentNullException(
"bytecode");
72 Initialize(device, bytecode, usedParameters);
84 return inputSignature;
109 public List<ShaderConstantBufferDescription> ConstantBuffers
113 return reflection.ConstantBuffers;
117 public void Apply(
bool applyEffectStates =
false)
119 Apply(graphicsDeviceDefault, applyEffectStates);
124 Apply(graphicsDeviceDefault, paramCollection1, applyEffectStates);
129 Apply(graphicsDeviceDefault, paramCollection1, paramCollection2, applyEffectStates);
134 Apply(graphicsDeviceDefault, paramCollection1, paramCollection2, paramCollection3, applyEffectStates);
139 Apply(graphicsDeviceDefault, paramCollection1, paramCollection2, paramCollection3, paramCollection4, applyEffectStates);
144 Apply(graphicsDeviceDefault, paramCollection1, paramCollection2, paramCollection3, paramCollection4, paramCollection5, applyEffectStates);
149 Apply(graphicsDeviceDefault, paramCollection1, paramCollection2, paramCollection3, paramCollection4, paramCollection5, paramCollection6, applyEffectStates);
154 Apply(graphicsDeviceDefault, parameterCollections, applyEffectStates);
159 UnbindResources(graphicsDeviceDefault);
162 internal EffectParameterResourceBinding GetParameterFastUpdater<T>(
ParameterKey<T> value)
164 for (
int i = 0; i < resourceBindings.Length; i++)
166 if (resourceBindings[i].Description.Param.Key == value)
168 return resourceBindings[i];
172 throw new ArgumentException(
"Parameter resource binding not found.",
"value");
177 PrepareApply(graphicsDevice);
178 var stageStatus = graphicsDevice.StageStatus;
180 stageStatus.ParameterCollections[0] = defaultParameters;
181 stageStatus.ParameterCollections[1] = parameters;
182 stageStatus.ParameterCollections[2] = graphicsDevice.Parameters;
183 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount);
184 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
189 PrepareApply(graphicsDevice);
190 var stageStatus = graphicsDevice.StageStatus;
192 stageStatus.ParameterCollections[0] = defaultParameters;
193 stageStatus.ParameterCollections[1] = parameters;
194 stageStatus.ParameterCollections[2] = paramCollection1;
195 stageStatus.ParameterCollections[3] = graphicsDevice.Parameters;
196 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 1);
197 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
202 PrepareApply(graphicsDevice);
203 var stageStatus = graphicsDevice.StageStatus;
205 stageStatus.ParameterCollections[0] = defaultParameters;
206 stageStatus.ParameterCollections[1] = parameters;
207 stageStatus.ParameterCollections[2] = paramCollection1;
208 stageStatus.ParameterCollections[3] = paramCollection2;
209 stageStatus.ParameterCollections[4] = graphicsDevice.Parameters;
210 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 2);
211 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
216 PrepareApply(graphicsDevice);
217 var stageStatus = graphicsDevice.StageStatus;
219 stageStatus.ParameterCollections[0] = defaultParameters;
220 stageStatus.ParameterCollections[1] = parameters;
221 stageStatus.ParameterCollections[2] = paramCollection1;
222 stageStatus.ParameterCollections[3] = paramCollection2;
223 stageStatus.ParameterCollections[4] = paramCollection3;
224 stageStatus.ParameterCollections[5] = graphicsDevice.Parameters;
225 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 3);
226 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
231 PrepareApply(graphicsDevice);
232 var stageStatus = graphicsDevice.StageStatus;
234 stageStatus.ParameterCollections[0] = defaultParameters;
235 stageStatus.ParameterCollections[1] = parameters;
236 stageStatus.ParameterCollections[2] = paramCollection1;
237 stageStatus.ParameterCollections[3] = paramCollection2;
238 stageStatus.ParameterCollections[4] = paramCollection3;
239 stageStatus.ParameterCollections[5] = paramCollection4;
240 stageStatus.ParameterCollections[6] = graphicsDevice.Parameters;
241 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 4);
242 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
247 PrepareApply(graphicsDevice);
248 var stageStatus = graphicsDevice.StageStatus;
250 stageStatus.ParameterCollections[0] = defaultParameters;
251 stageStatus.ParameterCollections[1] = parameters;
252 stageStatus.ParameterCollections[2] = paramCollection1;
253 stageStatus.ParameterCollections[3] = paramCollection2;
254 stageStatus.ParameterCollections[4] = paramCollection3;
255 stageStatus.ParameterCollections[5] = paramCollection4;
256 stageStatus.ParameterCollections[6] = paramCollection5;
257 stageStatus.ParameterCollections[7] = graphicsDevice.Parameters;
258 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 5);
259 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
264 PrepareApply(graphicsDevice);
265 var stageStatus = graphicsDevice.StageStatus;
267 stageStatus.ParameterCollections[0] = defaultParameters;
268 stageStatus.ParameterCollections[1] = parameters;
269 stageStatus.ParameterCollections[2] = paramCollection1;
270 stageStatus.ParameterCollections[3] = paramCollection2;
271 stageStatus.ParameterCollections[4] = paramCollection3;
272 stageStatus.ParameterCollections[5] = paramCollection4;
273 stageStatus.ParameterCollections[6] = paramCollection5;
274 stageStatus.ParameterCollections[7] = paramCollection6;
275 stageStatus.ParameterCollections[8] = graphicsDevice.Parameters;
276 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, DefaultParameterCollectionCount + 6);
277 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
282 if (parameterCollections == null)
throw new ArgumentNullException(
"parameterCollections");
284 PrepareApply(graphicsDevice);
285 var stageStatus = graphicsDevice.StageStatus;
287 if ((parameterCollections.Length + DefaultParameterCollectionCount) > stageStatus.ParameterCollections.Length)
289 throw new ArgumentException(
string.Format(
"Exceeding limit of number of parameter collections [{0}]", stageStatus.ParameterCollections.Length - DefaultParameterCollectionCount));
292 stageStatus.ParameterCollections[0] = defaultParameters;
293 stageStatus.ParameterCollections[1] = parameters;
294 for (
int i = 0; i < parameterCollections.Length; i++ )
296 stageStatus.ParameterCollections[i + DefaultParameterCollectionCount - 1] = parameterCollections[i];
298 stageStatus.ParameterCollections[parameterCollections.Length + DefaultParameterCollectionCount - 1] = graphicsDevice.Parameters;
299 stageStatus.UpdateParameters(graphicsDevice, updaterDefinition, parameterCollections.Length + DefaultParameterCollectionCount);
300 stageStatus.Apply(graphicsDevice, resourceBindings, ref effectStateBindings, applyEffectStates);
305 var stageStatus = graphicsDevice.StageStatus;
306 stageStatus.UnbindResources(graphicsDevice, resourceBindings);
311 return defaultParameters.ContainsKey(parameterKey);
316 if (graphicsDevice == null)
throw new ArgumentNullException(
"graphicsDevice");
318 program.Apply(graphicsDevice);
319 graphicsDevice.CurrentEffect =
this;
320 graphicsDevice.ApplyPlatformSpecificParams(
this);
325 Name = byteCode.Name;
326 graphicsDeviceDefault = device.RootDevice;
327 program = EffectProgram.New(graphicsDeviceDefault, byteCode);
328 reflection = byteCode.Reflection;
331 resourceBindings =
new EffectParameterResourceBinding[byteCode.Reflection.ResourceBindings.Count];
332 for (
int i = 0; i < resourceBindings.Length; i++)
334 resourceBindings[i].Description = byteCode.Reflection.ResourceBindings[i];
337 inputSignature = program.InputSignature;
338 LoadDefaultParameters();
342 if (usedParameters != null)
344 foreach (var parameter
in usedParameters)
347 CompilationParameters.SetObject(parameter.Key, parameter.Value);
351 foreach (var key
in CompilationParameters.Keys)
353 DefaultCompilationParameters.RegisterParameter(key,
false);
359 private void LoadDefaultParameters()
361 var shaderParameters = defaultParameters;
362 var constantBufferKeys =
new Dictionary<string, ParameterKey<ParameterConstantBuffer>>();
365 for (
int i = 0; i < resourceBindings.Length; i++)
368 var key = UpdateResourceBindingKey(ref resourceBindings[i].Description);
373 shaderParameters.RegisterParameter(key,
false);
378 foreach (var constantBuffer
in reflection.ConstantBuffers)
380 var constantBufferMembers = constantBuffer.Members;
382 for (
int i = 0; i < constantBufferMembers.Length; ++i)
385 var key = UpdateValueBindingKey(ref constantBufferMembers[i]);
388 shaderParameters.RegisterParameter(key,
false);
392 var parameterConstantBuffer =
new ParameterConstantBuffer(graphicsDeviceDefault, constantBuffer.Name, constantBuffer);
393 var constantBufferKey = ParameterKeys.New(parameterConstantBuffer, constantBuffer.Name);
394 shaderParameters.RegisterParameter(constantBufferKey,
false);
396 for (
int i = 0; i < resourceBindings.Length; i++)
398 if (resourceBindings[i].Description.Param.Class ==
EffectParameterClass.ConstantBuffer && resourceBindings[i].Description.Param.Key.Name == constantBuffer.Name)
400 resourceBindings[i].Description.Param.Key = constantBufferKey;
405 constantBufferKeys[constantBuffer.Name] = constantBufferKey;
411 graphicsDeviceDefault.StageStatus.PrepareBindings(resourceBindings);
416 var keyName = binding.Param.KeyName;
418 switch (binding.Param.Class)
420 case EffectParameterClass.Sampler:
422 binding.Param.Key = newSamplerKey;
423 var samplerBinding = reflection.SamplerStates.FirstOrDefault(x => x.KeyName == keyName);
424 if (samplerBinding != null)
426 samplerBinding.Key = newSamplerKey;
427 var samplerDescription = samplerBinding.Description;
428 defaultParameters.Set(newSamplerKey, SamplerState.New(graphicsDeviceDefault, samplerDescription));
431 case EffectParameterClass.ConstantBuffer:
432 case EffectParameterClass.TextureBuffer:
433 case EffectParameterClass.ShaderResourceView:
434 case EffectParameterClass.UnorderedAccessView:
435 switch (binding.Param.Type)
437 case EffectParameterType.Buffer:
438 case EffectParameterType.ConstantBuffer:
439 case EffectParameterType.TextureBuffer:
440 case EffectParameterType.AppendStructuredBuffer:
441 case EffectParameterType.ByteAddressBuffer:
442 case EffectParameterType.ConsumeStructuredBuffer:
443 case EffectParameterType.StructuredBuffer:
444 case EffectParameterType.RWBuffer:
445 case EffectParameterType.RWStructuredBuffer:
446 case EffectParameterType.RWByteAddressBuffer:
447 binding.Param.Key = FindOrCreateResourceKey<Buffer>(keyName);
449 case EffectParameterType.Texture1D:
450 case EffectParameterType.Texture1DArray:
451 case EffectParameterType.RWTexture1D:
452 case EffectParameterType.RWTexture1DArray:
453 binding.Param.Key = FindOrCreateResourceKey<Texture1D>(keyName);
455 case EffectParameterType.Texture2D:
456 case EffectParameterType.Texture2DArray:
457 case EffectParameterType.Texture2DMultisampled:
458 case EffectParameterType.Texture2DMultisampledArray:
459 case EffectParameterType.RWTexture2D:
460 case EffectParameterType.RWTexture2DArray:
461 binding.Param.Key = FindOrCreateResourceKey<Texture2D>(keyName);
463 case EffectParameterType.TextureCube:
464 case EffectParameterType.TextureCubeArray:
465 binding.Param.Key = FindOrCreateResourceKey<TextureCube>(keyName);
467 case EffectParameterType.RWTexture3D:
468 case EffectParameterType.Texture3D:
469 binding.Param.Key = FindOrCreateResourceKey<Texture3D>(keyName);
475 if (binding.Param.Key == null)
477 throw new InvalidOperationException(
string.Format(
"Unable to find/generate key [{0}] with unsupported type [{1}/{2}]", binding.Param.KeyName, binding.Param.Class, binding.Param.Type));
480 return binding.Param.Key;
485 switch (binding.Param.Class)
487 case EffectParameterClass.Scalar:
488 switch (binding.Param.Type)
490 case EffectParameterType.Bool:
491 binding.Param.Key = FindOrCreateValueKey<bool>(binding);
493 case EffectParameterType.Int:
494 binding.Param.Key = FindOrCreateValueKey<int>(binding);
496 case EffectParameterType.UInt:
497 binding.Param.Key = FindOrCreateValueKey<uint>(binding);
499 case EffectParameterType.Float:
500 binding.Param.Key = FindOrCreateValueKey<float>(binding);
504 case EffectParameterClass.Color:
506 var componentCount = binding.RowCount != 1 ? binding.RowCount : binding.ColumnCount;
507 switch (binding.Param.Type)
509 case EffectParameterType.Float:
510 binding.Param.Key = componentCount == 4
511 ? FindOrCreateValueKey<Color4>(binding)
519 var componentCount = binding.RowCount != 1 ? binding.RowCount : binding.ColumnCount;
520 switch (binding.Param.Type)
522 case EffectParameterType.Bool:
523 case EffectParameterType.Int:
524 binding.Param.Key = componentCount == 4 ? (
ParameterKey)FindOrCreateValueKey<Int4>(binding) : (componentCount == 3 ? FindOrCreateValueKey<Int3>(binding) : null);
526 case EffectParameterType.UInt:
527 binding.Param.Key = componentCount == 4 ? FindOrCreateValueKey<UInt4>(binding) : null;
529 case EffectParameterType.Float:
530 binding.Param.Key = componentCount == 4
531 ? FindOrCreateValueKey<Vector4>(binding)
532 : (componentCount == 3 ? (
ParameterKey)FindOrCreateValueKey<
Vector3>(binding) : (componentCount == 2 ? FindOrCreateValueKey<
Vector2>(binding) : null));
539 binding.Param.Key = FindOrCreateValueKey<
Matrix>(binding);
542 binding.Param.Key =
ParameterKeys.FindByName(binding.Param.KeyName);
546 if (binding.Param.Key == null)
548 throw new InvalidOperationException(
string.Format(
"Unable to find/generate key [{0}] with unsupported type [{1}/{2}]", binding.Param.KeyName, binding.Param.Class, binding.Param.Type));
551 if (binding.Count > 1)
554 binding.Param.Key = binding.Param.Key.CloneLength(binding.Count);
557 return binding.Param.Key;
560 private ParameterKey FindOrCreateResourceKey<T>(
string name)
562 return ParameterKeys.FindByName(name) ??
ParameterKeys.New<T>(name);
567 var name = binding.Param.KeyName;
568 return ParameterKeys.FindByName(name) ?? (binding.Count > 1 ? (
ParameterKey)ParameterKeys.New<
T[]>(name) :
ParameterKeys.New<T>(name));
571 private void UpdateKeyIndices()
575 var keys =
new HashSet<ParameterKey>();
577 var allParameterDependencies =
new Dictionary<ParameterKey, ParameterDependency>();
578 var parameterDependencies =
new HashSet<ParameterDependency>();
581 keys.Add(RasterizerStateKey);
582 keys.Add(DepthStencilStateKey);
583 keys.Add(BlendStateKey);
586 foreach (var dynamicValue
in defaultParameters.DynamicValues.Concat(parameters.DynamicValues))
588 allParameterDependencies[dynamicValue.Target] =
new ParameterDependency { Destination = dynamicValue.Target,
Dynamic = dynamicValue, Sources = dynamicValue.Dependencies };
593 foreach (var key
in defaultParameters.Keys)
595 UpdateRequiredKeys(keys, allParameterDependencies, key, parameterDependencies);
599 foreach (var key
in keys)
601 defaultParameters.RegisterParameter(key,
false);
607 var keyMapping = updaterDefinition.SortedKeys.Select((x, i) =>
new { x, i }).ToDictionary(k => k.x, k => k.i);
608 defaultParameters.SetKeyMapping(keyMapping);
609 parameters.SetKeyMapping(keyMapping);
611 for (
int i = 0; i < resourceBindings.Length; ++i)
613 resourceBindings[i].Description.Param.KeyIndex = Array.IndexOf(updaterDefinition.SortedKeys, resourceBindings[i].Description.Param.Key);
617 foreach (var internalValue
in defaultParameters.InternalValues)
619 var cb = internalValue.Value.Object as ParameterConstantBuffer;
622 for (
int i = 0; i < cb.ConstantBufferDesc.Members.Length; ++i)
624 var member = cb.ConstantBufferDesc.Members[i];
625 member.Param.KeyIndex = Array.IndexOf(updaterDefinition.SortedKeys, member.Param.Key);
626 cb.ConstantBufferDesc.Members[i] = member;
632 effectStateBindings.RasterizerStateKeyIndex = Array.IndexOf(updaterDefinition.SortedKeys, RasterizerStateKey);
633 effectStateBindings.DepthStencilStateKeyIndex = Array.IndexOf(updaterDefinition.SortedKeys, DepthStencilStateKey);
634 effectStateBindings.BlendStateKeyIndex = Array.IndexOf(updaterDefinition.SortedKeys, BlendStateKey);
637 private void UpdateRequiredKeys(HashSet<ParameterKey> requiredKeys, Dictionary<ParameterKey, ParameterDependency> allDependencies,
ParameterKey key, HashSet<ParameterDependency> requiredDependencies)
639 if (requiredKeys.Add(key))
642 if (allDependencies.TryGetValue(key, out dependency))
644 requiredDependencies.Add(dependency);
645 foreach (var source
in dependency.Sources)
650 if (sourceMetadata != null
651 && sourceMetadata.DefaultDynamicValue != null
652 && !allDependencies.ContainsKey(source))
654 allDependencies[source] =
new ParameterDependency { Destination = source,
Dynamic = sourceMetadata.DefaultDynamicValue, Sources = sourceMetadata.DefaultDynamicValue.Dependencies };
656 UpdateRequiredKeys(requiredKeys, allDependencies, source, requiredDependencies);
static readonly ParameterKey< GraphicsProfile > GraphicsProfileKey
The graphics profile target type.
A resource that is accessible by both the GPU (read only) and the CPU (write only). A dynamic resource is a good choice for a resource that will be updated by the CPU at least once per frame. To update a dynamic resource, use a Map method.
Describes a shader parameter for a valuetype (usually stored in constant buffers).
Key of an effect parameter.
void Apply(ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, bool applyEffectStates=false)
Represents a two dimensional mathematical vector.
Contains depth-stencil state for the device.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection[] parameterCollections, bool applyEffectStates)
Represents a color in the form of rgb.
Binary serialization method helpers to easily read/write data from a stream.
static readonly ParameterKey< GraphicsPlatform > GraphicsPlatformKey
The compiler platform type.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, ParameterCollection paramCollection2, bool applyEffectStates)
Parameters used for compilation.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, ParameterCollection paramCollection5, ParameterCollection paramCollection6, bool applyEffectStates)
Key of an gereric effect parameter.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, bool applyEffectStates)
Represents a three dimensional mathematical vector.
void Apply(ParameterCollection paramCollection1, ParameterCollection paramCollection2, bool applyEffectStates=false)
void Apply(ParameterCollection paramCollection1, bool applyEffectStates=false)
void Apply(ParameterCollection[] parameterCollections, bool applyEffectStates=false)
Effect(GraphicsDevice device, EffectBytecode bytecode, ParameterCollection usedParameters=null)
Initializes a new instance of the Effect class.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, bool applyEffectStates)
Base class for a framework component.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
Describes a shader parameter for a resource type.
bool HasParameter(ParameterKey parameterKey)
void Apply(ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, bool applyEffectStates=false)
void UnbindResources(GraphicsDevice graphicsDevice)
void Apply(ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, ParameterCollection paramCollection5, ParameterCollection paramCollection6, bool applyEffectStates=false)
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, bool applyEffectStates)
void Apply(bool applyEffectStates=false)
The reflection data describing the parameters of a shader.
Effect(GraphicsDevice device, byte[] bytecode)
Initializes a new instance of the Effect class.
void Apply(GraphicsDevice graphicsDevice, ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, ParameterCollection paramCollection5, bool applyEffectStates)
EffectParameterClass
Values that identify the class of a shader variable.
static readonly ParameterKey< bool > DebugKey
The debug flag.
Contains a compiled shader with bytecode for each stage.
A container to handle a hierarchical collection of effect variables.
void Apply(GraphicsDevice graphicsDevice, bool applyEffectStates)
void Apply(ParameterCollection paramCollection1, ParameterCollection paramCollection2, ParameterCollection paramCollection3, ParameterCollection paramCollection4, ParameterCollection paramCollection5, bool applyEffectStates=false)
Represents a 4x4 mathematical matrix.