OSDN Git Service

#36897 [DTXC] MIDIインポート機能の呼び出し口を、ファイルメニュー内にも配置。
[dtxmania/dtxmania.git] / SlimDXc_Jun2010(VC++2008) / source / direct3d9 / FragmentLinker.cpp
1 #include "stdafx.h"\r
2 /*\r
3 * Copyright (c) 2007-2010 SlimDX Group\r
4\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
11\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
14\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
21 * THE SOFTWARE.\r
22 */\r
23 #include "../VersionConfig.h"\r
24 #if SLIMDX_D3DX_VERSION < 42\r
25 \r
26 #include <d3d9.h>\r
27 #include <d3dx9.h>\r
28 \r
29 #include "../stack_array.h"\r
30 #include "../DataStream.h"\r
31 #include "../ComObject.h"\r
32 \r
33 #include "Direct3D9Exception.h"\r
34 \r
35 #include "Device.h"\r
36 #include "VertexShader9.h"\r
37 #include "PixelShader9.h"\r
38 #include "FragmentLinker.h"\r
39 \r
40 using namespace System;\r
41 using namespace System::Runtime::InteropServices;\r
42 \r
43 namespace SlimDX\r
44 {\r
45 namespace Direct3D9\r
46 {\r
47         FragmentLinker::FragmentLinker( SlimDX::Direct3D9::Device^ device, int cacheSize )\r
48         {\r
49                 IDirect3DDevice9* devicePointer = device->InternalPointer;\r
50                 ID3DXFragmentLinker* linker;\r
51 \r
52                 HRESULT hr = D3DXCreateFragmentLinker( devicePointer, cacheSize, &linker );\r
53                 RECORD_D3D9( hr );\r
54                 if( FAILED( hr ) )\r
55                         throw gcnew Direct3D9Exception( Result::Last );\r
56 \r
57                 Construct(linker);\r
58         }\r
59         \r
60         DataStream^ FragmentLinker::Gather( array<Byte>^ sourceData, array<Macro>^ defines,\r
61                 Include^ includeFile, ShaderFlags flags, [Out] String^% errors )\r
62         {\r
63                 ID3DXBuffer* fragmentBuffer;\r
64                 ID3DXBuffer* errorBuffer;\r
65                 pin_ptr<const Byte> pinnedData = &sourceData[0];\r
66 \r
67                 IncludeShim includeShim = IncludeShim( includeFile );\r
68                 ID3DXInclude* includePtr = NULL;\r
69                 if( includeFile != nullptr )\r
70                         includePtr = &includeShim;\r
71 \r
72                 array<GCHandle>^ handles;\r
73                 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );\r
74                 D3DXMACRO* macrosPtr = macros.size() > 0 ? &macros[0] : NULL;\r
75 \r
76 #pragma warning(push)\r
77 #pragma warning(disable:4996)\r
78                 HRESULT hr = D3DXGatherFragments( reinterpret_cast<LPCSTR>( pinnedData ), sourceData->Length, macrosPtr, includePtr,\r
79                         static_cast<DWORD>( flags ), &fragmentBuffer, &errorBuffer );\r
80 #pragma warning(pop)\r
81 \r
82                 //clean up after marshaling macros\r
83                 Macro::Unmarshal( handles );\r
84                 //marshal errors if necessary\r
85                 errors = Utilities::BufferToString( errorBuffer );\r
86                 \r
87                 if( RECORD_D3D9( hr ).IsFailure )\r
88                         return nullptr;\r
89 \r
90                 return gcnew DataStream( fragmentBuffer );\r
91         }\r
92 \r
93 // We know that Gather is obsolete, we declared it ourselves\r
94 #pragma warning(disable:4947)\r
95         DataStream^ FragmentLinker::Gather( String^ sourceData, array<Macro>^ defines,\r
96                 Include^ includeFile, ShaderFlags flags, [Out] String^% errors )\r
97         {\r
98                 array<Byte>^ sourceBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( sourceData );\r
99                 return Gather( sourceBytes, defines, includeFile, flags, errors );\r
100         }\r
101 #pragma warning(default:4947)\r
102 \r
103         DataStream^ FragmentLinker::GatherFromFile( String^ fileName, array<Macro>^ defines,\r
104                 Include^ includeFile, ShaderFlags flags, [Out] String^% errors )\r
105         {\r
106                 ID3DXBuffer* fragmentBuffer;\r
107                 ID3DXBuffer* errorBuffer;\r
108                 pin_ptr<const wchar_t> pinnedFile = PtrToStringChars( fileName );\r
109 \r
110                 IncludeShim includeShim = IncludeShim( includeFile );\r
111                 ID3DXInclude* includePtr = NULL;\r
112                 if( includeFile != nullptr )\r
113                         includePtr = &includeShim;\r
114 \r
115                 array<GCHandle>^ handles;\r
116                 stack_array<D3DXMACRO> macros = Macro::Marshal( defines, handles );\r
117                 D3DXMACRO* macrosPtr = macros.size() > 0 ? &macros[0] : NULL;\r
118 \r
119 #pragma warning(push)\r
120 #pragma warning(disable:4996)\r
121                 HRESULT hr = D3DXGatherFragmentsFromFile( reinterpret_cast<LPCTSTR>( pinnedFile ), macrosPtr, includePtr,\r
122                         static_cast<DWORD>( flags ), &fragmentBuffer, &errorBuffer );\r
123 #pragma warning(pop)\r
124 \r
125                 //clean up after marshaling macros\r
126                 Macro::Unmarshal( handles );\r
127                 //marshal errors if necessary\r
128                 errors = Utilities::BufferToString( errorBuffer );\r
129                 \r
130                 if( RECORD_D3D9( hr ).IsFailure )\r
131                         return nullptr;\r
132 \r
133                 return gcnew DataStream( fragmentBuffer );\r
134         }\r
135 \r
136         Result FragmentLinker::AddFragments( array<int>^ fragments )\r
137         {\r
138                 pin_ptr<int> pinnedFragments = &fragments[0];\r
139                 HRESULT hr = InternalPointer->AddFragments( reinterpret_cast<const DWORD*>( pinnedFragments ) );\r
140                 return RECORD_D3D9( hr );\r
141         }\r
142 \r
143         Result FragmentLinker::AddFragments( DataStream^ fragments )\r
144         {\r
145                 HRESULT hr = InternalPointer->AddFragments( reinterpret_cast<const DWORD*>( fragments->PositionPointer ) );\r
146                 return RECORD_D3D9( hr );\r
147         }\r
148 \r
149         DataStream^ FragmentLinker::GetFragment( EffectHandle^ name )\r
150         {\r
151                 D3DXHANDLE handle = name != nullptr ? name->InternalHandle : NULL;\r
152                 ID3DXBuffer* fragment;\r
153 \r
154                 HRESULT hr = InternalPointer->GetFragment( handle, &fragment );\r
155                 GC::KeepAlive( name );\r
156                 \r
157                 if( RECORD_D3D9( hr ).IsFailure )\r
158                         return nullptr;\r
159 \r
160                 return gcnew DataStream( fragment );\r
161         }\r
162 \r
163         DataStream^ FragmentLinker::Fragments::get()\r
164         {\r
165                 ID3DXBuffer* fragments;\r
166 \r
167                 HRESULT hr = InternalPointer->GetAllFragments( &fragments );\r
168                 \r
169                 if( RECORD_D3D9( hr ).IsFailure )\r
170                         return nullptr;\r
171 \r
172                 return gcnew DataStream( fragments );\r
173         }\r
174 \r
175         SlimDX::Direct3D9::Device^ FragmentLinker::Device::get()\r
176         {\r
177                 IDirect3DDevice9* device;\r
178                 //This method always returns the value S_OK.\r
179                 InternalPointer->GetDevice( &device );\r
180 \r
181                 return SlimDX::Direct3D9::Device::FromPointer( device );\r
182         }\r
183 \r
184         FragmentDescription FragmentLinker::GetFragmentDescription( EffectHandle^ name )\r
185         {\r
186                 D3DXHANDLE handle = name != nullptr ? name->InternalHandle : NULL;\r
187                 D3DXFRAGMENT_DESC description;\r
188 \r
189                 HRESULT hr = InternalPointer->GetFragmentDesc( handle, &description );\r
190                 GC::KeepAlive( name );\r
191                 if( RECORD_D3D9( hr ).IsFailure )\r
192                         return FragmentDescription();\r
193 \r
194                 FragmentDescription outDesc;\r
195                 outDesc.Name = gcnew String( description.Name );\r
196                 outDesc.Target = description.Target;\r
197 \r
198                 return outDesc;\r
199         }\r
200 \r
201         EffectHandle^ FragmentLinker::GetFragmentHandle( int index )\r
202         {\r
203                 D3DXHANDLE handle = InternalPointer->GetFragmentHandleByIndex( index );\r
204                 if( handle == NULL )\r
205                         return nullptr;\r
206 \r
207                 return gcnew EffectHandle( handle );\r
208         }\r
209 \r
210         EffectHandle^ FragmentLinker::GetFragmentHandle( String^ name )\r
211         {\r
212                 array<Byte>^ nameBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( name );\r
213                 pin_ptr<const Byte> pinnedName = &nameBytes[0];\r
214 \r
215                 D3DXHANDLE handle = InternalPointer->GetFragmentHandleByName( reinterpret_cast<LPCSTR>( pinnedName ) );\r
216                 if( handle == NULL )\r
217                         return nullptr;\r
218 \r
219                 return gcnew EffectHandle( handle );\r
220         }\r
221 \r
222         void FragmentLinker::ClearCache()\r
223         {\r
224                 //This method always returns the value S_OK.\r
225                 InternalPointer->ClearCache();\r
226         }\r
227 \r
228         ShaderBytecode^ FragmentLinker::LinkShader( String^ profile, ShaderFlags flags, array<EffectHandle^>^ fragmentHandles, [Out] String^% errors )\r
229         {\r
230                 ID3DXBuffer* bytecode;\r
231                 ID3DXBuffer* errorBuffer;\r
232                 array<Byte>^ profileBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( profile );\r
233                 pin_ptr<const Byte> pinnedProfile = &profileBytes[0];\r
234 \r
235                 stack_array<D3DXHANDLE> handles = stackalloc( D3DXHANDLE, fragmentHandles->Length );\r
236                 for( int i = 0; i < fragmentHandles->Length; ++i )\r
237                         handles[i] = fragmentHandles[i] != nullptr ? fragmentHandles[i]->InternalHandle : NULL;\r
238 \r
239                 HRESULT hr = InternalPointer->LinkShader( reinterpret_cast<LPCSTR>( pinnedProfile ), static_cast<DWORD>( flags ), &handles[0], fragmentHandles->Length, &bytecode, &errorBuffer );\r
240                 GC::KeepAlive( fragmentHandles );\r
241                 RECORD_D3D9( hr );\r
242                 \r
243                 //marshal errors if necessary\r
244                 errors = Utilities::BufferToString( errorBuffer );\r
245                 if( Result::Last.IsFailure )\r
246                         return nullptr;\r
247 \r
248                 return ShaderBytecode::FromPointer( bytecode );\r
249         }\r
250 \r
251         VertexShader^ FragmentLinker::LinkVertexShader( String^ profile, ShaderFlags flags, array<EffectHandle^>^ fragmentHandles, [Out] String^% errors )\r
252         {\r
253                 IDirect3DVertexShader9* shader;\r
254                 ID3DXBuffer* errorBuffer;\r
255                 array<Byte>^ profileBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( profile );\r
256                 pin_ptr<const Byte> pinnedProfile = &profileBytes[0];\r
257 \r
258                 stack_array<D3DXHANDLE> handles = stackalloc( D3DXHANDLE, fragmentHandles->Length );\r
259                 for( int i = 0; i < fragmentHandles->Length; ++i )\r
260                         handles[i] = fragmentHandles[i] != nullptr ? fragmentHandles[i]->InternalHandle : NULL;\r
261 \r
262                 HRESULT hr = InternalPointer->LinkVertexShader( reinterpret_cast<LPCSTR>( pinnedProfile ), static_cast<DWORD>( flags ), &handles[0], fragmentHandles->Length, &shader, &errorBuffer );\r
263                 GC::KeepAlive( fragmentHandles );\r
264                 RECORD_D3D9( hr );\r
265                 \r
266                 //marshal errors if necessary\r
267                 errors = Utilities::BufferToString( errorBuffer );\r
268                 if( Result::Last.IsFailure )\r
269                         return nullptr;\r
270 \r
271                 return VertexShader::FromPointer( shader );\r
272         }\r
273 \r
274         PixelShader^ FragmentLinker::LinkPixelShader( String^ profile, ShaderFlags flags, array<EffectHandle^>^ fragmentHandles, [Out] String^% errors )\r
275         {\r
276                 IDirect3DPixelShader9* shader;\r
277                 ID3DXBuffer* errorBuffer;\r
278                 array<Byte>^ profileBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( profile );\r
279                 pin_ptr<const Byte> pinnedProfile = &profileBytes[0];\r
280 \r
281                 stack_array<D3DXHANDLE> handles = stackalloc( D3DXHANDLE, fragmentHandles->Length);\r
282                 for( int i = 0; i < fragmentHandles->Length; ++i )\r
283                         handles[i] = fragmentHandles[i] != nullptr ? fragmentHandles[i]->InternalHandle : NULL;\r
284 \r
285                 HRESULT hr = InternalPointer->LinkPixelShader( reinterpret_cast<LPCSTR>( pinnedProfile ), static_cast<DWORD>( flags ), &handles[0], fragmentHandles->Length, &shader, &errorBuffer );\r
286                 GC::KeepAlive( fragmentHandles );\r
287                 RECORD_D3D9( hr );\r
288                 \r
289                 //marshal errors if necessary\r
290                 errors = Utilities::BufferToString( errorBuffer );\r
291                 if( Result::Last.IsFailure )\r
292                         return nullptr;\r
293 \r
294                 return PixelShader::FromPointer( shader );\r
295         }\r
296 \r
297         int FragmentLinker::FragmentCount::get()\r
298         {\r
299                 return InternalPointer->GetNumberOfFragments();\r
300         }\r
301 }\r
302 }\r
303 #endif\r