2 * Copyright (c) 2007-2010 SlimDX Group
\r
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
5 * of this software and associated documentation files (the "Software"), to deal
\r
6 * in the Software without restriction, including without limitation the rights
\r
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
8 * copies of the Software, and to permit persons to whom the Software is
\r
9 * furnished to do so, subject to the following conditions:
\r
11 * The above copyright notice and this permission notice shall be included in
\r
12 * all copies or substantial portions of the Software.
\r
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
24 #include "../CompilationException.h"
\r
25 #include "../DataStream.h"
\r
27 #include "D3DCompilerException.h"
\r
28 #include "ShaderBytecodeDC.h"
\r
30 using namespace System;
\r
31 using namespace System::IO;
\r
32 using namespace System::Text;
\r
33 using namespace System::Runtime::InteropServices;
\r
34 using namespace Microsoft::Win32::SafeHandles;
\r
38 namespace D3DCompiler
\r
40 ShaderBytecode::ShaderBytecode( const BYTE *data, UINT length )
\r
44 HRESULT hr = D3D10CreateBlob( length, &blob );
\r
45 if( RECORD_D3DC( hr ).IsFailure )
\r
46 throw gcnew D3DCompilerException( Result::Last );
\r
48 memcpy( blob->GetBufferPointer(), data, length );
\r
52 ShaderBytecode::ShaderBytecode( DataStream^ data )
\r
54 if( data == nullptr )
\r
55 throw gcnew ArgumentNullException( "data" );
\r
58 HRESULT hr = D3D10CreateBlob( static_cast<SIZE_T>(data->Length), &blob );
\r
59 if( RECORD_D3DC( hr ).IsFailure )
\r
60 throw gcnew D3DCompilerException( Result::Last );
\r
62 memcpy( blob->GetBufferPointer(), data->RawPointer, static_cast<size_t>(data->Length) );
\r
67 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
69 String^ compilationErrors;
\r
70 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
73 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
75 String^ compilationErrors;
\r
76 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
79 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
81 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
84 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
86 String^ compilationErrors;
\r
87 return Compile( shaderSource, entryPoint, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
90 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
92 String^ compilationErrors;
\r
93 return Compile( shaderSource, entryPoint, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
96 ShaderBytecode^ ShaderBytecode::Compile( String^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
98 if (String::IsNullOrEmpty(shaderSource))
\r
99 throw gcnew ArgumentNullException("shaderSource");
\r
101 return Compile( Encoding::ASCII->GetBytes( shaderSource ), entryPoint, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
104 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
106 String^ compilationErrors;
\r
107 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
110 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
112 String^ compilationErrors;
\r
113 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
116 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
118 return Compile( shaderSource, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
121 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
123 String^ compilationErrors;
\r
124 return Compile( shaderSource, entryPoint, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
127 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
129 String^ compilationErrors;
\r
130 return Compile( shaderSource, entryPoint, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
133 ShaderBytecode^ ShaderBytecode::Compile( array<Byte>^ shaderSource, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
136 ID3D10Blob *errors;
\r
138 if (shaderSource == nullptr)
\r
139 throw gcnew ArgumentNullException("shaderSource");
\r
140 if (profile == nullptr)
\r
141 throw gcnew ArgumentNullException("profile");
\r
142 if (shaderSource->Length == 0)
\r
143 throw gcnew ArgumentException("Empty shader source provided.", "shaderSource");
\r
145 pin_ptr<Byte> pinnedSource = &shaderSource[0];
\r
146 array<Byte>^ functionBytes = entryPoint == nullptr ? nullptr : System::Text::ASCIIEncoding::ASCII->GetBytes( entryPoint );
\r
147 pin_ptr<Byte> pinnedFunction = functionBytes == nullptr ? nullptr : &functionBytes[0];
\r
148 array<Byte>^ profileBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( profile );
\r
149 pin_ptr<Byte> pinnedProfile = &profileBytes[0];
\r
151 IncludeShim includeShim = IncludeShim( include );
\r
152 ID3D10Include* includePtr = NULL;
\r
153 if( include != nullptr )
\r
154 includePtr = &includeShim;
\r
156 array<GCHandle>^ handles;
\r
157 stack_array<D3D10_SHADER_MACRO> macros = ShaderMacro::Marshal( defines, handles );
\r
158 D3D10_SHADER_MACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
160 HRESULT hr = D3DCompile( reinterpret_cast<LPCSTR>( pinnedSource ), shaderSource->Length, NULL, macrosPtr, includePtr,
\r
161 reinterpret_cast<LPCSTR>( pinnedFunction ), reinterpret_cast<LPCSTR>( pinnedProfile ), static_cast<UINT>( shaderFlags ), static_cast<UINT>( effectFlags ), &code, &errors );
\r
163 ShaderMacro::Unmarshal( handles );
\r
165 compilationErrors = Utilities::BlobToString( errors );
\r
166 Exception^ e = CompilationException::Check<D3DCompilerException^>(hr, compilationErrors);
\r
170 return ShaderBytecode::FromPointer( code );
\r
173 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
175 String^ compilationErrors;
\r
176 return CompileFromFile( fileName, nullptr, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
179 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
181 String^ compilationErrors;
\r
182 return CompileFromFile( fileName, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
185 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
187 return CompileFromFile( fileName, nullptr, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
190 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags )
\r
192 String^ compilationErrors;
\r
193 return CompileFromFile( fileName, entryPoint, profile, shaderFlags, effectFlags, nullptr, nullptr, compilationErrors );
\r
196 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include )
\r
198 String^ compilationErrors;
\r
199 return CompileFromFile( fileName, entryPoint, profile, shaderFlags, effectFlags, defines, include, compilationErrors );
\r
202 ShaderBytecode^ ShaderBytecode::CompileFromFile( String^ fileName, String^ entryPoint, String^ profile, ShaderFlags shaderFlags, EffectFlags effectFlags, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
204 if (fileName == nullptr)
\r
205 throw gcnew ArgumentNullException("fileName");
\r
206 if (profile == nullptr)
\r
207 throw gcnew ArgumentNullException("profile");
\r
209 if (!File::Exists(fileName))
\r
210 throw gcnew FileNotFoundException("Could not open the shader or effect file.", fileName);
\r
212 return Compile(File::ReadAllText(fileName), entryPoint, profile, shaderFlags, effectFlags, defines, include, compilationErrors);
\r
215 String^ ShaderBytecode::Preprocess( String^ shaderSource )
\r
218 return Preprocess( shaderSource, nullptr, nullptr, errors );
\r
221 String^ ShaderBytecode::Preprocess( String^ shaderSource, array<ShaderMacro>^ defines, Include^ include )
\r
224 return Preprocess( shaderSource, defines, include, errors );
\r
227 String^ ShaderBytecode::Preprocess( String^ shaderSource, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
229 if (String::IsNullOrEmpty(shaderSource))
\r
230 throw gcnew ArgumentNullException("shaderSource");
\r
232 return Preprocess( Encoding::ASCII->GetBytes( shaderSource ), defines, include, compilationErrors );
\r
235 String^ ShaderBytecode::Preprocess( array<Byte>^ shaderSource )
\r
238 return Preprocess( shaderSource, nullptr, nullptr, errors );
\r
241 String^ ShaderBytecode::Preprocess( array<Byte>^ shaderSource, array<ShaderMacro>^ defines, Include^ include )
\r
244 return Preprocess( shaderSource, defines, include, errors );
\r
247 String^ ShaderBytecode::Preprocess( array<Byte>^ shaderSource, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
250 ID3D10Blob *errors;
\r
252 if (shaderSource == nullptr)
\r
253 throw gcnew ArgumentNullException("shaderSource");
\r
254 if (shaderSource->Length == 0)
\r
255 throw gcnew ArgumentException("Empty shader source provided.", "shaderSource");
\r
257 pin_ptr<Byte> pinnedSource = &shaderSource[0];
\r
259 IncludeShim includeShim = IncludeShim( include );
\r
260 ID3D10Include* includePtr = NULL;
\r
261 if( include != nullptr )
\r
262 includePtr = &includeShim;
\r
264 array<GCHandle>^ handles;
\r
265 stack_array<D3D10_SHADER_MACRO> macros = ShaderMacro::Marshal( defines, handles );
\r
266 D3D10_SHADER_MACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
268 HRESULT hr = D3DPreprocess( reinterpret_cast<LPCSTR>( pinnedSource ), shaderSource->Length, NULL, macrosPtr, includePtr, &code, &errors );
\r
269 ShaderMacro::Unmarshal( handles );
\r
271 compilationErrors = Utilities::BlobToString( errors );
\r
272 Exception^ e = CompilationException::Check<D3DCompilerException^>(hr, compilationErrors);
\r
276 return Utilities::BlobToString( code );
\r
279 String^ ShaderBytecode::PreprocessFromFile( String^ fileName )
\r
282 return PreprocessFromFile( fileName, nullptr, nullptr, errors );
\r
285 String^ ShaderBytecode::PreprocessFromFile( String^ fileName, array<ShaderMacro>^ defines, Include^ include )
\r
288 return PreprocessFromFile( fileName, defines, include, errors );
\r
291 String^ ShaderBytecode::PreprocessFromFile( String^ fileName, array<ShaderMacro>^ defines, Include^ include, [Out] String^ %compilationErrors )
\r
293 if (fileName == nullptr)
\r
294 throw gcnew ArgumentNullException("fileName");
\r
296 if (!File::Exists(fileName))
\r
297 throw gcnew FileNotFoundException("Could not open the shader or effect file.", fileName);
\r
299 return Preprocess(File::ReadAllText(fileName), defines, include, compilationErrors);
\r
302 String^ ShaderBytecode::Disassemble()
\r
304 return Disassemble(DisassemblyFlags::None, nullptr);
\r
307 String^ ShaderBytecode::Disassemble(DisassemblyFlags flags)
\r
309 return Disassemble(flags, nullptr);
\r
312 String^ ShaderBytecode::Disassemble(DisassemblyFlags flags, String^ comments)
\r
314 ID3D10Blob *output = NULL;
\r
316 array<unsigned char>^ bytes = comments == nullptr ? nullptr : Encoding::ASCII->GetBytes(comments);
\r
317 pin_ptr<unsigned char> pinnedBytes = bytes == nullptr ? nullptr : &bytes[0];
\r
319 HRESULT hr = D3DDisassemble(InternalPointer->GetBufferPointer(), InternalPointer->GetBufferSize(), static_cast<UINT>(flags), reinterpret_cast<LPCSTR>(pinnedBytes), &output);
\r
320 if (RECORD_D3DC(hr).IsFailure)
\r
323 return Utilities::BlobToString(output);
\r
326 String^ ShaderBytecode::Strip(StripFlags flags)
\r
328 ID3D10Blob *output = NULL;
\r
330 HRESULT hr = D3DStripShader(InternalPointer->GetBufferPointer(), InternalPointer->GetBufferSize(), static_cast<UINT>(flags), &output);
\r
331 if (RECORD_D3DC(hr).IsFailure)
\r
334 return Utilities::BlobToString(output);
\r
337 DataStream^ ShaderBytecode::Data::get()
\r
339 return gcnew DataStream( InternalPointer->GetBufferPointer(), InternalPointer->GetBufferSize(), true, true, false );
\r
342 int ShaderBytecode::GetHashCode()
\r
344 return reinterpret_cast<int>( InternalPointer->GetBufferPointer() );
\r