3 * Copyright (c) 2007-2010 SlimDX Group
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
6 * of this software and associated documentation files (the "Software"), to deal
\r
7 * in the Software without restriction, including without limitation the rights
\r
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
9 * copies of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in
\r
13 * all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
26 #include "../stack_array.h"
\r
27 #include "../DataStream.h"
\r
28 #include "../ComObject.h"
\r
29 #include "../CompilationException.h"
\r
31 #include "Direct3D9Exception.h"
\r
33 #include "EffectCompiler.h"
\r
35 using namespace System;
\r
36 using namespace System::IO;
\r
37 using namespace System::Runtime::InteropServices;
\r
43 EffectCompiler::EffectCompiler( String^ data, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags, [Out] String^% compilationErrors )
\r
45 ID3DXEffectCompiler* compiler;
\r
46 ID3DXBuffer* errorBuffer;
\r
48 array<Byte>^ dataBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( data );
\r
49 pin_ptr<Byte> pinnedData = &dataBytes[0];
\r
51 IncludeShim includeShim = IncludeShim( includeFile );
\r
52 ID3DXInclude* includePtr = NULL;
\r
53 if( includeFile != nullptr )
\r
54 includePtr = &includeShim;
\r
56 array<GCHandle>^ handles;
\r
57 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );
\r
58 D3DXMACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
60 HRESULT hr = D3DXCreateEffectCompiler( reinterpret_cast<LPCSTR>( pinnedData ), data->Length, macrosPtr, includePtr,
\r
61 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
63 Macro::Unmarshal( handles );
\r
64 compilationErrors = Utilities::BufferToString( errorBuffer );
\r
66 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
70 Construct( compiler );
\r
73 EffectCompiler::EffectCompiler( String^ data, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags )
\r
75 ID3DXEffectCompiler* compiler;
\r
76 ID3DXBuffer* errorBuffer;
\r
78 array<Byte>^ dataBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( data );
\r
79 pin_ptr<Byte> pinnedData = &dataBytes[0];
\r
81 IncludeShim includeShim = IncludeShim( includeFile );
\r
82 ID3DXInclude* includePtr = NULL;
\r
83 if( includeFile != nullptr )
\r
84 includePtr = &includeShim;
\r
86 array<GCHandle>^ handles;
\r
87 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );
\r
88 D3DXMACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
90 HRESULT hr = D3DXCreateEffectCompiler( reinterpret_cast<LPCSTR>( pinnedData ), data->Length, macrosPtr, includePtr,
\r
91 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
93 Macro::Unmarshal( handles );
\r
94 String^ compilationErrors = Utilities::BufferToString( errorBuffer );
\r
96 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
100 Construct( compiler );
\r
103 EffectCompiler::EffectCompiler( String^ data, ShaderFlags flags )
\r
105 ID3DXEffectCompiler* compiler;
\r
106 ID3DXBuffer* errorBuffer;
\r
108 array<Byte>^ dataBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( data );
\r
109 pin_ptr<Byte> pinnedData = &dataBytes[0];
\r
111 HRESULT hr = D3DXCreateEffectCompiler( reinterpret_cast<LPCSTR>( pinnedData ), data->Length, NULL, NULL,
\r
112 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
114 String^ compilationErrors = Utilities::BufferToString( errorBuffer );
\r
116 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
120 Construct( compiler );
\r
123 EffectCompiler^ EffectCompiler::FromMemory_Internal( const char* memory, UINT size, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags, String^* compilationErrors, Exception^* exception )
\r
125 ID3DXEffectCompiler* compiler;
\r
126 ID3DXBuffer* errorBuffer;
\r
128 IncludeShim includeShim = IncludeShim( includeFile );
\r
129 ID3DXInclude* includePtr = NULL;
\r
130 if( includeFile != nullptr )
\r
131 includePtr = &includeShim;
\r
133 array<GCHandle>^ handles;
\r
134 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );
\r
135 D3DXMACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
137 HRESULT hr = D3DXCreateEffectCompiler( memory, size, macrosPtr, includePtr,
\r
138 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
140 Macro::Unmarshal( handles );
\r
142 String^ compilationErrorsLocal = Utilities::BufferToString( errorBuffer );
\r
143 if( compilationErrors != NULL )
\r
144 *compilationErrors = compilationErrorsLocal;
\r
146 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrorsLocal );
\r
149 if( compilationErrors == NULL || exception == NULL )
\r
156 return EffectCompiler::FromPointer( compiler );
\r
159 EffectCompiler^ EffectCompiler::FromMemory( array<Byte>^ data, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags, [Out] String^% compilationErrors )
\r
161 pin_ptr<Byte> pinnedData = &data[0];
\r
162 String^ compileErrorsLocal;
\r
163 Exception^ e = nullptr;
\r
165 EffectCompiler^ effectCompiler = FromMemory_Internal( reinterpret_cast<const char*>( pinnedData ),
\r
166 static_cast<UINT>( data->Length ), defines, includeFile, flags, &compileErrorsLocal, &e );
\r
167 compilationErrors = compileErrorsLocal;
\r
172 return effectCompiler;
\r
175 EffectCompiler^ EffectCompiler::FromMemory( array<Byte>^ data, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags )
\r
177 pin_ptr<Byte> pinnedData = &data[0];
\r
179 return FromMemory_Internal( reinterpret_cast<const char*>( pinnedData ),
\r
180 static_cast<UINT>( data->Length ), defines, includeFile, flags, NULL, NULL );
\r
183 EffectCompiler^ EffectCompiler::FromMemory( array<Byte>^ data, ShaderFlags flags )
\r
185 pin_ptr<Byte> pinnedData = &data[0];
\r
187 return FromMemory_Internal( reinterpret_cast<const char*>( pinnedData ),
\r
188 static_cast<UINT>( data->Length ), nullptr, nullptr, flags, NULL, NULL );
\r
191 EffectCompiler^ EffectCompiler::FromStream( Stream^ stream, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags, [Out] String^% compilationErrors )
\r
193 DataStream^ ds = nullptr;
\r
194 array<Byte>^ data = Utilities::ReadStream( stream, &ds );
\r
195 Exception^ e = nullptr;
\r
197 if( data == nullptr )
\r
199 String^ compilationErrorsLocal;
\r
200 UINT size = static_cast<UINT>( ds->RemainingLength );
\r
201 EffectCompiler^ effectCompiler = FromMemory_Internal( ds->SeekToEnd(), size, defines, includeFile, flags, &compilationErrorsLocal, &e );
\r
203 compilationErrors = compilationErrorsLocal;
\r
207 return effectCompiler;
\r
210 return FromMemory( data, defines, includeFile, flags, compilationErrors );
\r
213 EffectCompiler^ EffectCompiler::FromStream( Stream^ stream, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags )
\r
215 DataStream^ ds = nullptr;
\r
216 array<Byte>^ data = Utilities::ReadStream( stream, &ds );
\r
217 if( data == nullptr )
\r
219 UINT size = static_cast<UINT>( ds->RemainingLength );
\r
220 return FromMemory_Internal( ds->SeekToEnd(), size, defines, includeFile, flags, NULL, NULL );
\r
223 return FromMemory( data, defines, includeFile, flags );
\r
226 EffectCompiler^ EffectCompiler::FromStream( Stream^ stream, ShaderFlags flags )
\r
228 DataStream^ ds = nullptr;
\r
229 array<Byte>^ data = Utilities::ReadStream( stream, &ds );
\r
230 if( data == nullptr )
\r
232 UINT size = static_cast<UINT>( ds->RemainingLength );
\r
233 return FromMemory_Internal( ds->SeekToEnd(), size, nullptr, nullptr, flags, NULL, NULL );
\r
236 return FromMemory( data, flags );
\r
239 EffectCompiler^ EffectCompiler::FromFile( String^ fileName, array<Macro>^ defines, Include^ includeFile,
\r
240 ShaderFlags flags, [Out] String^% errors )
\r
242 ID3DXEffectCompiler* compiler;
\r
243 ID3DXBuffer* errorBuffer;
\r
245 pin_ptr<const wchar_t> pinnedFile = PtrToStringChars( fileName );
\r
247 IncludeShim includeShim = IncludeShim( includeFile );
\r
248 ID3DXInclude* includePtr = NULL;
\r
249 if( includeFile != nullptr )
\r
250 includePtr = &includeShim;
\r
252 array<GCHandle>^ handles;
\r
253 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );
\r
254 D3DXMACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
256 HRESULT hr = D3DXCreateEffectCompilerFromFile( reinterpret_cast<LPCTSTR>( pinnedFile ), macrosPtr, includePtr,
\r
257 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
259 Macro::Unmarshal( handles );
\r
260 errors = Utilities::BufferToString( errorBuffer );
\r
262 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, errors );
\r
266 return EffectCompiler::FromPointer( compiler );
\r
269 EffectCompiler^ EffectCompiler::FromFile( String^ fileName, array<Macro>^ defines, Include^ includeFile, ShaderFlags flags )
\r
271 ID3DXEffectCompiler* compiler;
\r
272 ID3DXBuffer* errorBuffer;
\r
274 pin_ptr<const wchar_t> pinnedFile = PtrToStringChars( fileName );
\r
276 IncludeShim includeShim = IncludeShim( includeFile );
\r
277 ID3DXInclude* includePtr = NULL;
\r
278 if( includeFile != nullptr )
\r
279 includePtr = &includeShim;
\r
281 array<GCHandle>^ handles;
\r
282 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );
\r
283 D3DXMACRO* macrosPtr = macros.size() > 0 ? ¯os[0] : NULL;
\r
285 HRESULT hr = D3DXCreateEffectCompilerFromFile( reinterpret_cast<LPCTSTR>( pinnedFile ), macrosPtr, includePtr,
\r
286 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
288 Macro::Unmarshal( handles );
\r
289 String^ errors = Utilities::BufferToString( errorBuffer );
\r
291 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, errors );
\r
295 return EffectCompiler::FromPointer( compiler );
\r
298 EffectCompiler^ EffectCompiler::FromFile( String^ fileName, ShaderFlags flags )
\r
300 ID3DXEffectCompiler* compiler;
\r
301 ID3DXBuffer* errorBuffer;
\r
303 pin_ptr<const wchar_t> pinnedFile = PtrToStringChars( fileName );
\r
305 HRESULT hr = D3DXCreateEffectCompilerFromFile( reinterpret_cast<LPCTSTR>( pinnedFile ), NULL, NULL,
\r
306 static_cast<DWORD>( flags ), &compiler, &errorBuffer );
\r
308 String^ errors = Utilities::BufferToString( errorBuffer );
\r
310 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, errors );
\r
314 return EffectCompiler::FromPointer( compiler );
\r
317 ShaderBytecode^ EffectCompiler::CompileShader( EffectHandle^ functionHandle, String^ target, ShaderFlags flags,
\r
318 [Out] String^% compilationErrors, [Out] ConstantTable^% constantTable )
\r
320 D3DXHANDLE handle = functionHandle != nullptr ? functionHandle->InternalHandle : NULL;
\r
321 array<Byte>^ targetBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( target );
\r
322 pin_ptr<unsigned char> pinnedTarget = &targetBytes[0];
\r
324 ID3DXBuffer* errorBuffer;
\r
325 ID3DXBuffer* shader;
\r
326 ID3DXConstantTable* table;
\r
328 HRESULT hr = InternalPointer->CompileShader( handle, reinterpret_cast<LPCSTR>( pinnedTarget ), static_cast<DWORD>( flags ), &shader, &errorBuffer, &table );
\r
329 GC::KeepAlive( functionHandle );
\r
331 compilationErrors = Utilities::BufferToString( errorBuffer );
\r
333 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
337 constantTable = ConstantTable::FromPointer( table );
\r
338 return ShaderBytecode::FromPointer( shader );
\r
341 ShaderBytecode^ EffectCompiler::CompileShader( EffectHandle^ functionHandle, String^ target, ShaderFlags flags,
\r
342 [Out] String^% compilationErrors )
\r
344 D3DXHANDLE handle = functionHandle != nullptr ? functionHandle->InternalHandle : NULL;
\r
345 array<Byte>^ targetBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( target );
\r
346 pin_ptr<unsigned char> pinnedTarget = &targetBytes[0];
\r
348 ID3DXBuffer* errorBuffer;
\r
349 ID3DXBuffer* shader;
\r
351 HRESULT hr = InternalPointer->CompileShader( handle, reinterpret_cast<LPCSTR>( pinnedTarget ), static_cast<DWORD>( flags ), &shader, &errorBuffer, NULL );
\r
352 GC::KeepAlive( functionHandle );
\r
354 if( errorBuffer != NULL )
\r
355 compilationErrors = Utilities::BufferToString( errorBuffer );
\r
357 compilationErrors = String::Empty;
\r
359 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
363 return ShaderBytecode::FromPointer( shader );
\r
366 ShaderBytecode^ EffectCompiler::CompileShader( EffectHandle^ functionHandle, String^ target, ShaderFlags flags )
\r
369 return CompileShader( functionHandle, target, flags, errors );
\r
372 DataStream^ EffectCompiler::CompileEffect( ShaderFlags flags, [Out] String^% compilationErrors )
\r
374 ID3DXBuffer* effect;
\r
375 ID3DXBuffer* errorBuffer;
\r
377 HRESULT hr = InternalPointer->CompileEffect( static_cast<DWORD>( flags ), &effect, &errorBuffer );
\r
379 if( errorBuffer != NULL )
\r
380 compilationErrors = Utilities::BufferToString( errorBuffer );
\r
382 compilationErrors = String::Empty;
\r
384 Exception^ e = CompilationException::Check<Direct3D9Exception^>( hr, compilationErrors );
\r
388 return gcnew DataStream( effect );
\r
391 DataStream^ EffectCompiler::CompileEffect( ShaderFlags flags )
\r
394 return CompileEffect( flags, errors );
\r
397 Result EffectCompiler::SetLiteral( EffectHandle^ handle, bool literal )
\r
399 D3DXHANDLE nativeHandle = handle != nullptr ? handle->InternalHandle : NULL;
\r
400 HRESULT hr = InternalPointer->SetLiteral( nativeHandle, literal );
\r
401 GC::KeepAlive( handle );
\r
402 return RECORD_D3D9( hr );
\r
405 bool EffectCompiler::GetLiteral( EffectHandle^ handle )
\r
407 D3DXHANDLE nativeHandle = handle != nullptr ? handle->InternalHandle : NULL;
\r
408 BOOL literal = false;
\r
409 HRESULT hr = InternalPointer->GetLiteral( nativeHandle, &literal );
\r
410 GC::KeepAlive( handle );
\r
413 return literal > 0;
\r