// Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// -----------------------------------------------------------------------------
// Original code from SlimDX project, ported from C++/CLI.
// Greetings to SlimDX Group. Original code published with the following license:
// -----------------------------------------------------------------------------
/*
* Copyright (c) 2007-2011 SlimDX Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using SharpDX.Direct3D;
namespace SharpDX.Direct3D9
{
///
/// Represents the compiled bytecode of a shader or effect.
///
/// Blob
public class ShaderBytecode : DisposeBase
{
private bool isOwner;
private Blob blob;
private ConstantTable constantTable;
///
/// Initializes a new instance of the class.
///
/// A containing the compiled bytecode.
public ShaderBytecode(DataStream data)
{
CreateFromPointer(data.PositionPointer, (int)(data.Length - data.Position));
}
///
/// Initializes a new instance of the class.
///
/// A containing the compiled bytecode.
public ShaderBytecode(Stream data)
{
int size = (int)(data.Length - data.Position);
byte[] localBuffer = new byte[size];
data.Read(localBuffer, 0, size);
CreateFromBuffer(localBuffer);
}
///
/// Initializes a new instance of the class.
///
/// The buffer.
public ShaderBytecode(byte[] buffer)
{
CreateFromBuffer(buffer);
}
///
/// Initializes a new instance of the class.
///
/// a pointer to a compiler bytecode
/// size of the bytecode
public ShaderBytecode(IntPtr buffer, int sizeInBytes)
{
BufferPointer = buffer;
BufferSize = sizeInBytes;
}
///
/// Initializes a new instance of the class.
///
/// The BLOB.
protected internal ShaderBytecode(Blob blob)
{
this.blob = blob;
BufferPointer = blob.BufferPointer;
BufferSize = blob.BufferSize;
}
///
/// Gets the buffer pointer.
///
public System.IntPtr BufferPointer { get; private set; }
///
/// Gets or sets the size of the buffer.
///
///
/// The size of the buffer.
///
public SharpDX.PointerSize BufferSize { get; set; }
///
/// Gets the shader constant table.
///
/// HRESULT D3DXGetShaderConstantTable([In] const void* pFunction,[In] ID3DXConstantTable** ppConstantTable)
public ConstantTable ConstantTable
{
get
{
if (constantTable != null)
return constantTable;
return constantTable = D3DX9.GetShaderConstantTable(BufferPointer);
}
}
///
/// Gets the version of the shader.
///
/// unsigned int D3DXGetShaderVersion([In] const void* pFunction)
public int Version
{
get
{
return D3DX9.GetShaderVersion(BufferPointer);
}
}
///
/// Gets the size of the shader from a function pointer.
///
/// The shader function pointer.
/// Size of the shader
public static int GetShaderSize(IntPtr shaderFunctionPtr)
{
return D3DX9.GetShaderSize(shaderFunctionPtr);
}
///
/// Assembles a shader from the given source data.
///
/// The source shader data.
/// Compilation options.
/// A object representing the raw shader stream.
/// HRESULT D3DXAssembleShader([In] const void* pSrcData,[In] unsigned int SrcDataLen,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs)
public static CompilationResult Assemble(byte[] sourceData, ShaderFlags flags)
{
return Assemble(sourceData, null, null, flags);
}
///
/// Assembles a shader from the given source data.
///
/// The source shader data.
/// Compilation options.
/// A object representing the raw shader stream.
/// HRESULT D3DXAssembleShader([In] const void* pSrcData,[In] unsigned int SrcDataLen,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs)
public static CompilationResult Assemble(string sourceData, ShaderFlags flags)
{
return Assemble(sourceData, null, null, flags);
}
///
/// Assembles a shader from the given source data.
///
/// The source shader data.
/// Macro definitions.
/// An interface to use for handling #include directives.
/// Compilation options.
/// A object representing the raw shader stream.
/// HRESULT D3DXAssembleShader([In] const void* pSrcData,[In] unsigned int SrcDataLen,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs)
public static CompilationResult Assemble(string sourceData, Macro[] defines, Include includeFile, ShaderFlags flags)
{
return Assemble(Encoding.ASCII.GetBytes(sourceData), defines, includeFile, flags);
}
///
/// Assembles a shader from the given source data.
///
/// The source shader data.
/// Macro definitions.
/// An interface to use for handling #include directives.
/// Compilation options.
/// A object representing the raw shader stream.
/// HRESULT D3DXAssembleShader([In] const void* pSrcData,[In] unsigned int SrcDataLen,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs)
public static CompilationResult Assemble(byte[] sourceData, Macro[] defines, Include includeFile, ShaderFlags flags)
{
unsafe
{
var resultCode = Result.Ok;
Blob blobForCode = null;
Blob blobForErrors = null;
try
{
fixed (void* pData = sourceData)
D3DX9.AssembleShader(
(IntPtr)pData,
sourceData.Length,
PrepareMacros(defines),
IncludeShadow.ToIntPtr(includeFile),
(int)flags,
out blobForCode,
out blobForErrors);
}
catch (SharpDXException ex)
{
if (blobForErrors != null)
{
resultCode = ex.ResultCode;
if (Configuration.ThrowOnShaderCompileError)
throw new CompilationException(ex.ResultCode, Utilities.BlobToString(blobForErrors));
}
else
{
throw;
}
}
return new CompilationResult(blobForCode != null ? new ShaderBytecode(blobForCode) : null, resultCode, Utilities.BlobToString(blobForErrors));
}
}
///
/// Assembles a shader from file.
///
/// Name of the shader file.
/// Compilation options.
/// A object representing the raw shader stream.
public static CompilationResult AssembleFromFile(string fileName, ShaderFlags flags)
{
return AssembleFromFile(fileName, null, null, flags);
}
///
/// Assembles a shader from file.
///
/// Name of the shader file.
/// Macro definitions.
/// An interface to use for handling #include directives.
/// Compilation options.
///
/// A object representing the raw shader stream.
///
public static CompilationResult AssembleFromFile(string fileName, Macro[] defines, Include includeFile, ShaderFlags flags)
{
return Assemble(File.ReadAllText(fileName), defines, includeFile, flags);
}
///
/// Compiles the provided shader or effect source.
///
/// A string containing the source of the shader or effect to compile.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(string shaderSource, string profile, ShaderFlags shaderFlags)
{
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
return Compile(Encoding.ASCII.GetBytes(shaderSource), null, profile, shaderFlags, null, null);
}
///
/// Compiles the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to compile.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(byte[] shaderSource, string profile, ShaderFlags shaderFlags)
{
return Compile(shaderSource, null, profile, shaderFlags, null, null);
}
///
/// Compiles the provided shader or effect source.
///
/// A string containing the source of the shader or effect to compile.
/// The name of the shader entry-point function, or null for an effect file.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(string shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags)
{
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
return Compile(Encoding.ASCII.GetBytes(shaderSource), entryPoint, profile, shaderFlags, null, null);
}
///
/// Compiles the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to compile.
/// The name of the shader entry-point function, or null for an effect file.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(byte[] shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags)
{
return Compile(shaderSource, entryPoint, profile, shaderFlags, null, null);
}
///
/// Compiles the provided shader or effect source.
///
/// A string containing the source of the shader or effect to compile.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(string shaderSource, string profile, ShaderFlags shaderFlags, Macro[] defines, Include include)
{
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
return Compile(Encoding.ASCII.GetBytes(shaderSource), null, profile, shaderFlags, defines, include);
}
///
/// Compiles the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to compile.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(byte[] shaderSource, string profile, ShaderFlags shaderFlags, Macro[] defines, Include include)
{
return Compile(shaderSource, null, profile, shaderFlags, defines, include);
}
///
/// Compiles the provided shader or effect source.
///
/// A string containing the source of the shader or effect to compile.
/// The name of the shader entry-point function, or null for an effect file.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(string shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags, Macro[] defines, Include include)
{
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
return Compile(Encoding.ASCII.GetBytes(shaderSource), entryPoint, profile, shaderFlags, defines, include);
}
///
/// Compiles a shader or effect from a file on disk.
///
/// The name of the source file to compile.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult CompileFromFile(string fileName, string profile, ShaderFlags shaderFlags = ShaderFlags.None, Macro[] defines = null, Include include = null)
{
return CompileFromFile(fileName, null, profile, shaderFlags, defines, include);
}
///
/// Compiles a shader or effect from a file on disk.
///
/// The name of the source file to compile.
/// The name of the shader entry-point function, or null for an effect file.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult CompileFromFile(string fileName, string entryPoint, string profile, ShaderFlags shaderFlags = ShaderFlags.None, Macro[] defines = null, Include include = null)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
if (profile == null)
{
throw new ArgumentNullException("profile");
}
if (!File.Exists(fileName))
{
throw new FileNotFoundException("Could not open the shader or effect file.", fileName);
}
return Compile(File.ReadAllText(fileName), entryPoint, profile, shaderFlags, PrepareMacros(defines), include);
}
///
/// Compiles the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to compile.
/// The name of the shader entry-point function, or null for an effect file.
/// The shader target or set of shader features to compile against.
/// Shader compilation options.
/// A set of macros to define during compilation.
/// An interface for handling include files.
///
/// The compiled shader bytecode, or null if the method fails.
///
/// HRESULT D3DXCompileShader([In] const char* pSrcData,[In] unsigned int SrcDataLen,[In] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] const char* pFunctionName,[In] const char* pProfile,[In] unsigned int Flags,[In] ID3DXBuffer** ppShader,[In] ID3DXBuffer** ppErrorMsgs,[In] ID3DXConstantTable** ppConstantTable)
public static CompilationResult Compile(byte[] shaderSource, string entryPoint, string profile, ShaderFlags shaderFlags, Macro[] defines, Include include)
{
unsafe
{
var resultCode = Result.Ok;
Blob blobForCode = null;
Blob blobForErrors = null;
ConstantTable constantTable = null;
try
{
fixed (void* pData = &shaderSource[0])
D3DX9.CompileShader(
(IntPtr)pData,
shaderSource.Length,
PrepareMacros(defines),
IncludeShadow.ToIntPtr(include),
entryPoint,
profile,
(int)shaderFlags,
out blobForCode,
out blobForErrors,
out constantTable);
}
catch (SharpDXException ex)
{
if (blobForErrors != null)
{
resultCode = ex.ResultCode;
if (Configuration.ThrowOnShaderCompileError)
throw new CompilationException(ex.ResultCode, Utilities.BlobToString(blobForErrors));
}
else
{
throw;
}
}
finally
{
if (constantTable != null)
constantTable.Dispose();
}
return new CompilationResult(blobForCode != null ? new ShaderBytecode(blobForCode) : null, resultCode, Utilities.BlobToString(blobForErrors));
}
}
///
/// Disassembles compiled HLSL code back into textual source.
///
/// The textual source of the shader or effect.
/// HRESULT D3DXDisassembleShader([In] const void* pShader,[In] BOOL EnableColorCode,[In] const char* pComments,[In] ID3DXBuffer** ppDisassembly)
public string Disassemble()
{
return this.Disassemble(false, null);
}
///
/// Disassembles compiled HLSL code back into textual source.
///
/// if set to true [enable color code].
///
/// The textual source of the shader or effect.
///
/// HRESULT D3DXDisassembleShader([In] const void* pShader,[In] BOOL EnableColorCode,[In] const char* pComments,[In] ID3DXBuffer** ppDisassembly)
public string Disassemble(bool enableColorCode)
{
return this.Disassemble(enableColorCode, null);
}
///
/// Disassembles compiled HLSL code back into textual source.
///
/// if set to true [enable color code].
/// Commenting information to embed in the disassembly.
///
/// The textual source of the shader or effect.
///
/// HRESULT D3DXDisassembleShader([In] const void* pShader,[In] BOOL EnableColorCode,[In] const char* pComments,[In] ID3DXBuffer** ppDisassembly)
public string Disassemble(bool enableColorCode, string comments)
{
Blob output;
D3DX9.DisassembleShader(BufferPointer, enableColorCode, comments, out output);
return Utilities.BlobToString(output);
}
///
/// Searches through the shader for the specified comment.
///
/// A FOURCC code used to identify the comment.
/// The comment data.
/// HRESULT D3DXFindShaderComment([In] const void* pFunction,[In] unsigned int FourCC,[Out] const void** ppData,[Out] unsigned int* pSizeInBytes)
public DataStream FindComment(Format fourCC)
{
IntPtr buffer;
int size;
D3DX9.FindShaderComment(BufferPointer, (int)fourCC, out buffer, out size);
return new DataStream(buffer, size, true, true);
}
///
/// Gets the set of semantics for shader inputs.
///
/// The set of semantics for shader inputs.
/// HRESULT D3DXGetShaderInputSemantics([In] const void* pFunction,[In, Out, Buffer] D3DXSEMANTIC* pSemantics,[InOut] unsigned int* pCount)
public ShaderSemantic[] GetInputSemantics()
{
int count = 0;
D3DX9.GetShaderInputSemantics(BufferPointer, null, ref count);
if (count == 0)
return null;
var buffer = new ShaderSemantic[count];
D3DX9.GetShaderInputSemantics(BufferPointer, buffer, ref count);
return buffer;
}
///
/// Gets the set of semantics for shader outputs.
///
/// The set of semantics for shader outputs.
/// HRESULT D3DXGetShaderOutputSemantics([In] const void* pFunction,[In, Out, Buffer] D3DXSEMANTIC* pSemantics,[InOut] unsigned int* pCount)
public ShaderSemantic[] GetOutputSemantics()
{
int count = 0;
D3DX9.GetShaderOutputSemantics(BufferPointer, null, ref count);
if (count == 0)
return null;
var buffer = new ShaderSemantic[count];
D3DX9.GetShaderOutputSemantics(BufferPointer, buffer, ref count);
return buffer;
}
///
/// Gets the sampler names references in the shader.
///
/// The set of referenced sampler names.
/// HRESULT D3DXGetShaderSamplers([In] const void* pFunction,[In] const char** pSamplers,[In] unsigned int* pCount)
public string[] GetSamplers()
{
unsafe
{
int count = 0;
D3DX9.GetShaderSamplers(BufferPointer, IntPtr.Zero, ref count);
if (count == 0)
return null;
var result = new string[count];
if (count < 1024)
{
var pointers = stackalloc IntPtr[count];
D3DX9.GetShaderSamplers(BufferPointer, (IntPtr)pointers, ref count);
for (int i = 0; i < count; i++)
result[i] = Marshal.PtrToStringAnsi(pointers[i]);
}
else
{
var pointers = new IntPtr[count];
fixed (void* pPointers = pointers)
D3DX9.GetShaderSamplers(BufferPointer, (IntPtr)pPointers, ref count);
for (int i = 0; i < count; i++)
result[i] = Marshal.PtrToStringAnsi(pointers[i]);
}
return result;
}
}
///
/// Extracts the major version component of a shader version number.
///
/// The shader version number.
/// The major version component.
public static int MajorVersion(int version)
{
return ((version >> 8) & 0xff);
}
///
/// Extracts the minor version component of a shader version number.
///
/// The shader version number.
/// The minor version component.
public static int MinorVersion(int version)
{
return (version & 0xff);
}
///
/// Converts a shader version number into a managed object.
///
/// The shader version number.
/// The parsed shader version information.
public static Version ParseVersion(int version)
{
return new Version((version >> 8) & 0xff, version & 0xff);
}
///
/// Loads from the specified stream.
///
/// The stream.
/// A shader bytecode
public static ShaderBytecode Load(Stream stream)
{
var buffer = Utilities.ReadStream(stream);
return new ShaderBytecode(buffer);
}
///
/// Saves to the specified file name.
///
/// Name of the file.
public void Save(string fileName)
{
using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
Save(stream);
}
///
/// Saves this bytecode to the specified stream.
///
/// The stream.
public void Save(Stream stream)
{
if (BufferSize == 0) return;
var buffer = new byte[BufferSize];
Utilities.Read(BufferPointer, buffer, 0, buffer.Length);
stream.Write(buffer, 0, buffer.Length);
}
///
/// Create a ShaderBytecode from a pointer.
///
/// The pointer.
///
public static ShaderBytecode FromPointer(IntPtr pointer)
{
// TODO: check that pointer is a blob?
return new ShaderBytecode(new Blob(pointer));
}
///
/// Preprocesses the provided shader or effect source.
///
/// A string containing the source of the shader or effect to preprocess.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string Preprocess(string shaderSource, Macro[] defines = null, Include include = null)
{
string errors = null;
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
var shaderSourcePtr = Marshal.StringToHGlobalAnsi(shaderSource);
try
{
return Preprocess(shaderSourcePtr, shaderSource.Length, defines, include, out errors);
}
finally
{
if (shaderSourcePtr != IntPtr.Zero)
Marshal.FreeHGlobal(shaderSourcePtr);
}
}
///
/// Preprocesses the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to preprocess.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string Preprocess(byte[] shaderSource, Macro[] defines = null, Include include = null)
{
string errors = null;
return Preprocess(shaderSource, defines, include, out errors);
}
///
/// Preprocesses the provided shader or effect source.
///
/// An array of bytes containing the raw source of the shader or effect to preprocess.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// When the method completes, contains a string of compilation errors, or an empty string if preprocessing succeeded.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string Preprocess(byte[] shaderSource, Macro[] defines, Include include, out string compilationErrors)
{
unsafe
{
fixed (void* pData = &shaderSource[0])
return Preprocess((IntPtr)pData, shaderSource.Length, defines, include, out compilationErrors);
}
}
///
/// Preprocesses the provided shader or effect source.
///
/// The shader source PTR.
/// Length of the shader source.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// When the method completes, contains a string of compilation errors, or an empty string if preprocessing succeeded.
///
/// The preprocessed shader source.
///
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string Preprocess(IntPtr shaderSourcePtr, int shaderSourceLength, Macro[] defines, Include include, out string compilationErrors)
{
unsafe
{
Blob blobForText = null;
Blob blobForErrors = null;
compilationErrors = null;
try
{
D3DX9.PreprocessShader(shaderSourcePtr, shaderSourceLength, PrepareMacros(defines), IncludeShadow.ToIntPtr(include), out blobForText, out blobForErrors);
}
catch (SharpDXException ex)
{
if (blobForErrors != null)
{
compilationErrors = Utilities.BlobToString(blobForErrors);
throw new CompilationException(ex.ResultCode, compilationErrors);
}
throw;
}
return Utilities.BlobToString(blobForText);
}
}
///
/// Preprocesses the provided shader or effect source.
///
/// A string containing the source of the shader or effect to preprocess.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// When the method completes, contains a string of compilation errors, or an empty string if preprocessing succeeded.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string Preprocess(string shaderSource, Macro[] defines, Include include, out string compilationErrors)
{
if (string.IsNullOrEmpty(shaderSource))
{
throw new ArgumentNullException("shaderSource");
}
var shaderSourcePtr = Marshal.StringToHGlobalAnsi(shaderSource);
try
{
return Preprocess(shaderSourcePtr, shaderSource.Length, defines, include, out compilationErrors);
}
finally
{
if (shaderSourcePtr != IntPtr.Zero)
Marshal.FreeHGlobal(shaderSourcePtr);
}
}
///
/// Preprocesses a shader or effect from a file on disk.
///
/// The name of the source file to compile.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string PreprocessFromFile(string fileName)
{
string errors = null;
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
if (!File.Exists(fileName))
{
throw new FileNotFoundException("Could not open the shader or effect file.", fileName);
}
string str = File.ReadAllText(fileName);
if (string.IsNullOrEmpty(str))
{
throw new ArgumentNullException("fileName");
}
return Preprocess(Encoding.ASCII.GetBytes(str), null, null, out errors);
}
///
/// Preprocesses a shader or effect from a file on disk.
///
/// The name of the source file to compile.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string PreprocessFromFile(string fileName, Macro[] defines, Include include)
{
string errors = null;
return PreprocessFromFile(fileName, defines, include, out errors);
}
///
/// Preprocesses a shader or effect from a file on disk.
///
/// The name of the source file to compile.
/// A set of macros to define during preprocessing.
/// An interface for handling include files.
/// When the method completes, contains a string of compilation errors, or an empty string if preprocessing succeeded.
/// The preprocessed shader source.
/// HRESULT D3DXPreprocessShader([In] const void* pSrcData,[In] unsigned int SrcDataSize,[In, Buffer] const D3DXMACRO* pDefines,[In] ID3DXInclude* pInclude,[In] ID3DXBuffer** ppShaderText,[In] ID3DXBuffer** ppErrorMsgs)
public static string PreprocessFromFile(string fileName, Macro[] defines, Include include, out string compilationErrors)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
if (!File.Exists(fileName))
{
throw new FileNotFoundException("Could not open the shader or effect file.", fileName);
}
return Preprocess(File.ReadAllText(fileName), defines, include, out compilationErrors);
}
///
/// Gets the raw data of the compiled bytecode.
///
public DataStream Data
{
get { return new DataStream(BufferPointer, BufferSize, true, true); }
}
///
/// Read a compiled shader bytecode from a Stream and return a ShaderBytecode
///
///
///
public static ShaderBytecode FromStream(Stream stream)
{
return new ShaderBytecode(stream);
}
///
/// Read a compiled shader bytecode from a Stream and return a ShaderBytecode
///
///
///
public static ShaderBytecode FromFile(string fileName)
{
return new ShaderBytecode(File.ReadAllBytes(fileName));
}
internal static Macro[] PrepareMacros(Macro[] macros)
{
if (macros == null)
return null;
if (macros.Length == 0)
return null;
if (macros[macros.Length - 1].Name == null && macros[macros.Length - 1].Definition == null)
return macros;
var macroArray = new Macro[macros.Length + 1];
Array.Copy(macros, macroArray, macros.Length);
macroArray[macros.Length] = new Macro(null, null);
return macroArray;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (blob != null)
{
blob.Dispose();
blob = null;
}
if (constantTable != null)
{
constantTable.Dispose();
constantTable = null;
}
}
if (isOwner && BufferPointer != IntPtr.Zero)
{
Marshal.FreeHGlobal(BufferPointer);
BufferPointer = IntPtr.Zero;
BufferSize = 0;
}
}
private void CreateFromBuffer(byte[] buffer)
{
unsafe
{
fixed (void* pBuffer = &buffer[0])
CreateFromPointer((IntPtr)pBuffer, buffer.Length);
}
}
private void CreateFromPointer(IntPtr buffer, int sizeInBytes)
{
// D3DCommon.CreateBlob(sizeInBytes, this);
BufferPointer = Marshal.AllocHGlobal(sizeInBytes);
BufferSize = sizeInBytes;
isOwner = true;
Utilities.CopyMemory(BufferPointer, buffer, sizeInBytes);
}
}
}