1 | /*
|
---|
2 | -----------------------------------------------------------------------------
|
---|
3 | This source file is part of OGRE
|
---|
4 | (Object-oriented Graphics Rendering Engine)
|
---|
5 | For the latest info, see http://www.ogre3d.org/
|
---|
6 |
|
---|
7 | Copyright (c) 2000-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #include "OgreD3D9HLSLProgram.h"
|
---|
26 | #include "OgreGpuProgramManager.h"
|
---|
27 | #include "OgreStringConverter.h"
|
---|
28 | #include "OgreD3D9GpuProgram.h"
|
---|
29 | #include "OgreGpuProgram.h"
|
---|
30 | #include "OgreRoot.h"
|
---|
31 | #include "OgreRenderSystem.h"
|
---|
32 | #include "OgreRenderSystemCapabilities.h"
|
---|
33 |
|
---|
34 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
35 | #include "OgreFileSystem.h"
|
---|
36 | #endif
|
---|
37 |
|
---|
38 | namespace Ogre {
|
---|
39 | //-----------------------------------------------------------------------
|
---|
40 | D3D9HLSLProgram::CmdEntryPoint D3D9HLSLProgram::msCmdEntryPoint;
|
---|
41 | D3D9HLSLProgram::CmdTarget D3D9HLSLProgram::msCmdTarget;
|
---|
42 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
43 | D3D9HLSLProgram::CmdOptimalization D3D9HLSLProgram::msCmdOptimalization;
|
---|
44 | D3D9HLSLProgram::CmdFlowControl D3D9HLSLProgram::msCmdFlowControl;
|
---|
45 | #endif
|
---|
46 | //-----------------------------------------------------------------------
|
---|
47 | //-----------------------------------------------------------------------
|
---|
48 | void D3D9HLSLProgram::loadFromSource(void)
|
---|
49 | {
|
---|
50 | LPD3DXBUFFER errors = 0;
|
---|
51 |
|
---|
52 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
53 | mCompilerFlags = NULL;
|
---|
54 |
|
---|
55 | if(!mOptimalization)
|
---|
56 | mCompilerFlags = D3DXSHADER_SKIPOPTIMIZATION;
|
---|
57 | if(mFlowControl == 1)
|
---|
58 | mCompilerFlags = mCompilerFlags|D3DXSHADER_PREFER_FLOW_CONTROL;
|
---|
59 | if(mFlowControl == -1)
|
---|
60 | mCompilerFlags = mCompilerFlags|D3DXSHADER_AVOID_FLOW_CONTROL;
|
---|
61 |
|
---|
62 | HRESULT hr = D3DXCompileShader(
|
---|
63 | mSource.c_str(),
|
---|
64 | static_cast<UINT>(mSource.length()),
|
---|
65 | NULL, //no preprocessor defines
|
---|
66 | NULL, //no includes
|
---|
67 | mEntryPoint.c_str(),
|
---|
68 | mTarget.c_str(),
|
---|
69 | mCompilerFlags,
|
---|
70 | &mpMicroCode,
|
---|
71 | &errors,
|
---|
72 | &mpConstTable);
|
---|
73 | #else
|
---|
74 | // Compile & assemble into microcode
|
---|
75 | HRESULT hr = D3DXCompileShader(
|
---|
76 | mSource.c_str(),
|
---|
77 | static_cast<UINT>(mSource.length()),
|
---|
78 | NULL, //no preprocessor defines
|
---|
79 | NULL, //no includes
|
---|
80 | mEntryPoint.c_str(),
|
---|
81 | mTarget.c_str(),
|
---|
82 | NULL, // no compile flags
|
---|
83 | &mpMicroCode,
|
---|
84 | &errors,
|
---|
85 | &mpConstTable);
|
---|
86 | #endif
|
---|
87 |
|
---|
88 | if (FAILED(hr))
|
---|
89 | {
|
---|
90 | String message = "Cannot assemble D3D9 high-level shader " + mName + " Errors:\n" +
|
---|
91 | static_cast<const char*>(errors->GetBufferPointer());
|
---|
92 | errors->Release();
|
---|
93 | OGRE_EXCEPT(hr, message,
|
---|
94 | "D3D9HLSLProgram::loadFromSource");
|
---|
95 | }
|
---|
96 |
|
---|
97 |
|
---|
98 | }
|
---|
99 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
100 | //-----------------------------------------------------------------------
|
---|
101 | void D3D9HLSLProgram::loadHighLevelImpl(void)
|
---|
102 | {
|
---|
103 | if (mLoadFromFile)
|
---|
104 | loadFromFile();
|
---|
105 | else
|
---|
106 | loadFromSource();
|
---|
107 | }
|
---|
108 | void D3D9HLSLProgram::loadFromFile(void)
|
---|
109 | {
|
---|
110 | DataStreamPtr stream =
|
---|
111 | ResourceGroupManager::getSingleton().openResource(
|
---|
112 | mFilename, mGroup, true, this);
|
---|
113 |
|
---|
114 | mSource = "";
|
---|
115 |
|
---|
116 | while(!stream->eof())
|
---|
117 | {
|
---|
118 | String line = stream->getLine();
|
---|
119 | if(line.find("#include")!= line.npos)
|
---|
120 | {
|
---|
121 | int firstocc = line.find("\"",0);
|
---|
122 | int secondocc = line.find("\"",firstocc+1);
|
---|
123 | String filename = line.substr(firstocc+1,secondocc - firstocc - 1);
|
---|
124 |
|
---|
125 | DataStreamPtr includedstream = ResourceGroupManager::getSingleton().openResource(
|
---|
126 | filename, mGroup, true, 0);
|
---|
127 | while(!includedstream->eof())
|
---|
128 | {
|
---|
129 | line = includedstream->getLine();
|
---|
130 | mSource.append(line);
|
---|
131 | mSource.append("\n");
|
---|
132 | }
|
---|
133 | }
|
---|
134 | else
|
---|
135 | mSource.append(line);
|
---|
136 | mSource.append("\n");
|
---|
137 | }
|
---|
138 | // mSource.append(0);
|
---|
139 | // mSource = stream->getAsString();
|
---|
140 | loadFromSource();
|
---|
141 | /*
|
---|
142 | LPD3DXBUFFER errors = 0;
|
---|
143 |
|
---|
144 | mCompilerFlags = NULL;
|
---|
145 |
|
---|
146 | if(!mOptimalization)
|
---|
147 | mCompilerFlags = D3DXSHADER_SKIPOPTIMIZATION;
|
---|
148 | if(mFlowControl == 1)
|
---|
149 | mCompilerFlags = mCompilerFlags|D3DXSHADER_PREFER_FLOW_CONTROL;
|
---|
150 | if(mFlowControl == -1)
|
---|
151 | mCompilerFlags = mCompilerFlags|D3DXSHADER_AVOID_FLOW_CONTROL;
|
---|
152 |
|
---|
153 | FileInfoListPtr fileInfos = ResourceGroupManager::getSingleton().findResourceFileInfo(mGroup, mFilename);
|
---|
154 | FileInfo FI = fileInfos->at(0);
|
---|
155 | String fullPathName = ((FileSystemArchive*)FI.archive)->getTmpPath()+"\\"+
|
---|
156 | ((FileSystemArchive*)FI.archive)->getBasePath() +"\\"+
|
---|
157 | mFilename;
|
---|
158 | String Fname2 = "C:\GameToolsSVN\Ogre\Ogre1.2\Samples\Media\DeferredShadingMedia\DeferredShading\material\hlsl\vs.hlsl";
|
---|
159 | HRESULT hr = D3DXCompileShaderFromFile(
|
---|
160 | fullPathName.c_str(),
|
---|
161 | NULL, //no preprocessor defines
|
---|
162 | NULL, //no includes
|
---|
163 | mEntryPoint.c_str(),
|
---|
164 | mTarget.c_str(),
|
---|
165 | mCompilerFlags,
|
---|
166 | &mpMicroCode,
|
---|
167 | &errors,
|
---|
168 | &mpConstTable);
|
---|
169 |
|
---|
170 | if (FAILED(hr))
|
---|
171 | {
|
---|
172 | String message = "Cannot assemble D3D9 high-level shader " + mName + " Errors:\n" +
|
---|
173 | static_cast<const char*>(errors->GetBufferPointer());
|
---|
174 | errors->Release();
|
---|
175 | OGRE_EXCEPT(hr, message,
|
---|
176 | "D3D9HLSLProgram::loadFromSource");
|
---|
177 | }*/
|
---|
178 | }
|
---|
179 | #endif
|
---|
180 | //-----------------------------------------------------------------------
|
---|
181 | void D3D9HLSLProgram::createLowLevelImpl(void)
|
---|
182 | {
|
---|
183 | // Create a low-level program, give it the same name as us
|
---|
184 | mAssemblerProgram =
|
---|
185 | GpuProgramManager::getSingleton().createProgramFromString(
|
---|
186 | mName,
|
---|
187 | mGroup,
|
---|
188 | "",// dummy source, since we'll be using microcode
|
---|
189 | mType,
|
---|
190 | mTarget);
|
---|
191 | static_cast<D3D9GpuProgram*>(mAssemblerProgram.get())->setExternalMicrocode(mpMicroCode);
|
---|
192 |
|
---|
193 | }
|
---|
194 | //-----------------------------------------------------------------------
|
---|
195 | void D3D9HLSLProgram::unloadHighLevelImpl(void)
|
---|
196 | {
|
---|
197 | SAFE_RELEASE(mpMicroCode);
|
---|
198 | SAFE_RELEASE(mpConstTable);
|
---|
199 |
|
---|
200 | }
|
---|
201 | //-----------------------------------------------------------------------
|
---|
202 | void D3D9HLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
|
---|
203 | {
|
---|
204 | // Derive parameter names from const table
|
---|
205 | assert(mpConstTable && "Program not loaded!");
|
---|
206 | // Get contents of the constant table
|
---|
207 | D3DXCONSTANTTABLE_DESC desc;
|
---|
208 | HRESULT hr = mpConstTable->GetDesc(&desc);
|
---|
209 |
|
---|
210 | if (FAILED(hr))
|
---|
211 | {
|
---|
212 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
|
---|
213 | "Cannot retrieve constant descriptions from HLSL program.",
|
---|
214 | "D3D9HLSLProgram::populateParameterNames");
|
---|
215 | }
|
---|
216 | // Iterate over the constants
|
---|
217 | for (unsigned int i = 0; i < desc.Constants; ++i)
|
---|
218 | {
|
---|
219 | // Recursively descend through the structure levels
|
---|
220 | // Since D3D9 has no nice 'leaf' method like Cg (sigh)
|
---|
221 | processParamElement(NULL, "", i, params);
|
---|
222 | }
|
---|
223 |
|
---|
224 |
|
---|
225 | }
|
---|
226 | //-----------------------------------------------------------------------
|
---|
227 | void D3D9HLSLProgram::processParamElement(D3DXHANDLE parent, String prefix,
|
---|
228 | unsigned int index, GpuProgramParametersSharedPtr params)
|
---|
229 | {
|
---|
230 | D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
|
---|
231 |
|
---|
232 | // Since D3D HLSL doesn't deal with naming of array and struct parameters
|
---|
233 | // automatically, we have to do it by hand
|
---|
234 |
|
---|
235 | D3DXCONSTANT_DESC desc;
|
---|
236 | unsigned int numParams = 1;
|
---|
237 | HRESULT hr = mpConstTable->GetConstantDesc(hConstant, &desc, &numParams);
|
---|
238 | if (FAILED(hr))
|
---|
239 | {
|
---|
240 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
|
---|
241 | "Cannot retrieve constant description from HLSL program.",
|
---|
242 | "D3D9HLSLProgram::processParamElement");
|
---|
243 | }
|
---|
244 |
|
---|
245 | String paramName = desc.Name;
|
---|
246 | // trim the odd '$' which appears at the start of the names in HLSL
|
---|
247 | if (paramName.at(0) == '$')
|
---|
248 | paramName.erase(paramName.begin());
|
---|
249 |
|
---|
250 | // If it's an array, elements will be > 1
|
---|
251 | for (unsigned int e = 0; e < desc.Elements; ++e)
|
---|
252 | {
|
---|
253 | if (desc.Class == D3DXPC_STRUCT)
|
---|
254 | {
|
---|
255 | // work out a new prefix for nested members, if it's an array, we need an index
|
---|
256 | if (desc.Elements > 1)
|
---|
257 | prefix = prefix + paramName + "[" + StringConverter::toString(e) + "].";
|
---|
258 | else
|
---|
259 | prefix = prefix + paramName + ".";
|
---|
260 | // Cascade into struct
|
---|
261 | for (unsigned int i = 0; i < desc.StructMembers; ++i)
|
---|
262 | {
|
---|
263 | processParamElement(hConstant, prefix, i, params);
|
---|
264 | }
|
---|
265 | }
|
---|
266 | else
|
---|
267 | {
|
---|
268 | // Process params
|
---|
269 | if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
|
---|
270 | {
|
---|
271 | size_t paramIndex = desc.RegisterIndex;
|
---|
272 | String name = prefix + paramName;
|
---|
273 | // If this is an array, need to append element index
|
---|
274 | if (desc.Elements > 1)
|
---|
275 | name += "[" + StringConverter::toString(e) + "]";
|
---|
276 |
|
---|
277 | params->_mapParameterNameToIndex(name, paramIndex);
|
---|
278 | // setup constant definition
|
---|
279 | // is it float or int
|
---|
280 | GpuProgramParameters::ElementType elementType = GpuProgramParameters::ET_INT;
|
---|
281 | if (desc.Type == D3DXPT_FLOAT)
|
---|
282 | elementType = GpuProgramParameters::ET_REAL;
|
---|
283 | params->addConstantDefinition(name, paramIndex, 0, elementType);
|
---|
284 | }
|
---|
285 | }
|
---|
286 | }
|
---|
287 |
|
---|
288 | }
|
---|
289 | //-----------------------------------------------------------------------
|
---|
290 | D3D9HLSLProgram::D3D9HLSLProgram(ResourceManager* creator, const String& name,
|
---|
291 | ResourceHandle handle, const String& group, bool isManual,
|
---|
292 | ManualResourceLoader* loader)
|
---|
293 | : HighLevelGpuProgram(creator, name, handle, group, isManual, loader)
|
---|
294 | , mpMicroCode(NULL), mpConstTable(NULL)
|
---|
295 | {
|
---|
296 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
297 | mOptimalization = true;
|
---|
298 | mFlowControl = 0;
|
---|
299 | mCompilerFlags = NULL;
|
---|
300 | #endif
|
---|
301 |
|
---|
302 | if (createParamDictionary("D3D9HLSLProgram"))
|
---|
303 | {
|
---|
304 | setupBaseParamDictionary();
|
---|
305 | ParamDictionary* dict = getParamDictionary();
|
---|
306 |
|
---|
307 | dict->addParameter(ParameterDef("entry_point",
|
---|
308 | "The entry point for the HLSL program.",
|
---|
309 | PT_STRING),&msCmdEntryPoint);
|
---|
310 | dict->addParameter(ParameterDef("target",
|
---|
311 | "Name of the assembler target to compile down to.",
|
---|
312 | PT_STRING),&msCmdTarget);
|
---|
313 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
314 | dict->addParameter(ParameterDef("optimalization",
|
---|
315 | "Boolean to turn optimalization on/off",
|
---|
316 | PT_STRING),&msCmdOptimalization);
|
---|
317 | dict->addParameter(ParameterDef("flow_control",
|
---|
318 | "Flow control: default, prefer, avoid.",
|
---|
319 | PT_STRING),&msCmdFlowControl);
|
---|
320 | #endif
|
---|
321 | }
|
---|
322 |
|
---|
323 | }
|
---|
324 | //-----------------------------------------------------------------------
|
---|
325 | D3D9HLSLProgram::~D3D9HLSLProgram()
|
---|
326 | {
|
---|
327 | // have to call this here reather than in Resource destructor
|
---|
328 | // since calling virtual methods in base destructors causes crash
|
---|
329 | if (mIsLoaded)
|
---|
330 | {
|
---|
331 | unload();
|
---|
332 | }
|
---|
333 | else
|
---|
334 | {
|
---|
335 | unloadHighLevel();
|
---|
336 | }
|
---|
337 | }
|
---|
338 | //-----------------------------------------------------------------------
|
---|
339 | bool D3D9HLSLProgram::isSupported(void) const
|
---|
340 | {
|
---|
341 | // If skeletal animation is being done, we need support for UBYTE4
|
---|
342 | if (isSkeletalAnimationIncluded() &&
|
---|
343 | !Root::getSingleton().getRenderSystem()->getCapabilities()
|
---|
344 | ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
|
---|
345 | {
|
---|
346 | return false;
|
---|
347 | }
|
---|
348 |
|
---|
349 | return GpuProgramManager::getSingleton().isSyntaxSupported(mTarget);
|
---|
350 | }
|
---|
351 | //-----------------------------------------------------------------------
|
---|
352 | GpuProgramParametersSharedPtr D3D9HLSLProgram::createParameters(void)
|
---|
353 | {
|
---|
354 | // Call superclass
|
---|
355 | GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters();
|
---|
356 |
|
---|
357 | // D3D HLSL uses column-major matrices
|
---|
358 | params->setTransposeMatrices(true);
|
---|
359 |
|
---|
360 | return params;
|
---|
361 | }
|
---|
362 | //-----------------------------------------------------------------------
|
---|
363 | void D3D9HLSLProgram::setTarget(const String& target)
|
---|
364 | {
|
---|
365 | mTarget = target;
|
---|
366 | }
|
---|
367 |
|
---|
368 | //-----------------------------------------------------------------------
|
---|
369 | const String& D3D9HLSLProgram::getLanguage(void) const
|
---|
370 | {
|
---|
371 | static const String language = "hlsl";
|
---|
372 |
|
---|
373 | return language;
|
---|
374 | }
|
---|
375 |
|
---|
376 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
377 | void D3D9HLSLProgram::setOptimalization(const String& optimalization)
|
---|
378 | {
|
---|
379 | mOptimalization = StringConverter::parseBool(optimalization);
|
---|
380 | }
|
---|
381 | const String& D3D9HLSLProgram::getOptimalization() const
|
---|
382 | {
|
---|
383 | return StringConverter::toString(mOptimalization);
|
---|
384 | }
|
---|
385 | void D3D9HLSLProgram::setFlowControl(const String& control)
|
---|
386 | {
|
---|
387 | if(control == "default")
|
---|
388 | mFlowControl = 0;
|
---|
389 | else if(control == "avoid")
|
---|
390 | mFlowControl = -1;
|
---|
391 | else if(control == "prefer")
|
---|
392 | mFlowControl = 1;
|
---|
393 | }
|
---|
394 | const String& D3D9HLSLProgram::getFlowControl() const
|
---|
395 | {
|
---|
396 | static const String def = "default";
|
---|
397 | static const String pref = "prefer";
|
---|
398 | static const String av = "avoid";
|
---|
399 | if(mFlowControl == 0)
|
---|
400 | return def;
|
---|
401 | if(mFlowControl == -1)
|
---|
402 | return av;
|
---|
403 | if(mFlowControl == 1)
|
---|
404 | return pref;
|
---|
405 | }
|
---|
406 | #endif
|
---|
407 |
|
---|
408 | //-----------------------------------------------------------------------
|
---|
409 | //-----------------------------------------------------------------------
|
---|
410 | String D3D9HLSLProgram::CmdEntryPoint::doGet(const void *target) const
|
---|
411 | {
|
---|
412 | return static_cast<const D3D9HLSLProgram*>(target)->getEntryPoint();
|
---|
413 | }
|
---|
414 | void D3D9HLSLProgram::CmdEntryPoint::doSet(void *target, const String& val)
|
---|
415 | {
|
---|
416 | static_cast<D3D9HLSLProgram*>(target)->setEntryPoint(val);
|
---|
417 | }
|
---|
418 | //-----------------------------------------------------------------------
|
---|
419 | String D3D9HLSLProgram::CmdTarget::doGet(const void *target) const
|
---|
420 | {
|
---|
421 | return static_cast<const D3D9HLSLProgram*>(target)->getTarget();
|
---|
422 | }
|
---|
423 | void D3D9HLSLProgram::CmdTarget::doSet(void *target, const String& val)
|
---|
424 | {
|
---|
425 | static_cast<D3D9HLSLProgram*>(target)->setTarget(val);
|
---|
426 | }
|
---|
427 |
|
---|
428 | #ifdef GAMETOOLS_ILLUMINATION_MODULE
|
---|
429 | String D3D9HLSLProgram::CmdOptimalization::doGet(const void *target) const
|
---|
430 | {
|
---|
431 | return static_cast<const D3D9HLSLProgram*>(target)->getOptimalization();
|
---|
432 | }
|
---|
433 | void D3D9HLSLProgram::CmdOptimalization::doSet(void *target, const String& val)
|
---|
434 | {
|
---|
435 | static_cast<D3D9HLSLProgram*>(target)->setOptimalization(val);
|
---|
436 | }
|
---|
437 | String D3D9HLSLProgram::CmdFlowControl::doGet(const void *target) const
|
---|
438 | {
|
---|
439 | return static_cast<const D3D9HLSLProgram*>(target)->getFlowControl();
|
---|
440 | }
|
---|
441 | void D3D9HLSLProgram::CmdFlowControl::doSet(void *target, const String& val)
|
---|
442 | {
|
---|
443 | static_cast<D3D9HLSLProgram*>(target)->setFlowControl(val);
|
---|
444 | }
|
---|
445 | #endif
|
---|
446 |
|
---|
447 | }
|
---|