gfxD3D11Shader.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2015 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "gfx/D3D11/gfxD3D11Shader.h"
  24. #include "core/frameAllocator.h"
  25. #include "core/stream/fileStream.h"
  26. #include "core/util/safeDelete.h"
  27. #include "console/console.h"
  28. extern bool gDisassembleAllShaders;
  29. #pragma comment(lib, "d3dcompiler.lib")
  30. gfxD3DIncludeRef GFXD3D11Shader::smD3DInclude = NULL;
  31. class gfxD3D11Include : public ID3DInclude, public StrongRefBase
  32. {
  33. private:
  34. Vector<String> mLastPath;
  35. public:
  36. void setPath(const String &path)
  37. {
  38. mLastPath.clear();
  39. mLastPath.push_back(path);
  40. }
  41. gfxD3D11Include() {}
  42. virtual ~gfxD3D11Include() {}
  43. STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes);
  44. STDMETHOD(Close)(THIS_ LPCVOID pData);
  45. };
  46. HRESULT gfxD3D11Include::Open(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes)
  47. {
  48. using namespace Torque;
  49. // First try making the path relative to the parent.
  50. Torque::Path path = Torque::Path::Join( mLastPath.last(), '/', pFileName );
  51. path = Torque::Path::CompressPath( path );
  52. if ( !Torque::FS::ReadFile( path, (void *&)*ppData, *pBytes, true ) )
  53. {
  54. // Ok... now try using the path as is.
  55. path = String( pFileName );
  56. path = Torque::Path::CompressPath( path );
  57. if ( !Torque::FS::ReadFile( path, (void *&)*ppData, *pBytes, true ) )
  58. {
  59. AssertISV(false, avar( "Failed to open include '%s'.", pFileName));
  60. return E_FAIL;
  61. }
  62. }
  63. // If the data was of zero size then we cannot recurse
  64. // into this file and DX won't call Close() below.
  65. //
  66. // So in this case don't push on the path.
  67. if ( *pBytes > 0 )
  68. mLastPath.push_back( path.getRootAndPath() );
  69. return S_OK;
  70. }
  71. HRESULT gfxD3D11Include::Close( THIS_ LPCVOID pData )
  72. {
  73. // Free the data file and pop its path off the stack.
  74. delete [] (U8*)pData;
  75. mLastPath.pop_back();
  76. return S_OK;
  77. }
  78. GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader)
  79. : mShader(shader),
  80. mInstancingConstant(false)
  81. {
  82. dMemset(&mDesc, 0, sizeof(mDesc));
  83. mValid = false;
  84. mStageFlags = 0;
  85. }
  86. GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
  87. const GFXShaderConstDesc& desc)
  88. : mShader(shader),
  89. mDesc(desc),
  90. mInstancingConstant(false)
  91. {
  92. if (desc.constType == GFXSCT_ConstBuffer)
  93. mValid = false;
  94. else
  95. mValid = true;
  96. addDesc(desc.shaderStage, desc);
  97. mStageFlags = desc.shaderStage;
  98. }
  99. GFXD3D11ShaderConstHandle::~GFXD3D11ShaderConstHandle()
  100. {
  101. }
  102. void GFXD3D11ShaderConstHandle::addDesc(GFXShaderStage stage, const GFXShaderConstDesc& desc)
  103. {
  104. // just add for now.
  105. mDescMap[stage] = desc;
  106. }
  107. const GFXShaderConstDesc GFXD3D11ShaderConstHandle::getDesc(GFXShaderStage stage)
  108. {
  109. return mDescMap[stage];
  110. }
  111. //------------------------------------------------------------------------------
  112. GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader)
  113. {
  114. mShader = shader;
  115. mDeviceContext = D3D11DEVICECONTEXT;
  116. for (U32 i = 0; i < 6; i++)
  117. {
  118. for (U32 j = 0; j < 16; j++)
  119. {
  120. mBoundBuffers[i][j] = nullptr;
  121. }
  122. }
  123. }
  124. GFXD3D11ShaderConstBuffer::~GFXD3D11ShaderConstBuffer()
  125. {
  126. for (auto& pair : mBufferMap) {
  127. delete[] pair.value.data;
  128. }
  129. mBufferMap.clear(); // Clear the map
  130. for (U32 i = 0; i < 6; i++)
  131. {
  132. for (U32 j = 0; j < 16; j++)
  133. {
  134. mBoundBuffers[i][j] = nullptr;
  135. }
  136. }
  137. if (mShader)
  138. mShader->_unlinkBuffer(this);
  139. }
  140. GFXShader* GFXD3D11ShaderConstBuffer::getShader()
  141. {
  142. return mShader;
  143. }
  144. void GFXD3D11ShaderConstBuffer::setMatrix(const GFXShaderConstDesc& constDesc, const U32 inSize, const void* data, U8* basePointer)
  145. {
  146. U8* buf = basePointer;
  147. if (constDesc.constType == GFXSCT_Float4x4)
  148. {
  149. // Special case, we can just blast this guy.
  150. if (dMemcmp(buf + constDesc.offset, data, inSize) != 0)
  151. {
  152. dMemcpy(buf + constDesc.offset, data, inSize);
  153. }
  154. return;
  155. }
  156. else
  157. {
  158. PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
  159. // Figure out how big of a chunk we are copying. We're going to copy 4 columns by N rows of data
  160. U32 csize;
  161. switch (constDesc.constType)
  162. {
  163. case GFXSCT_Float2x2:
  164. csize = 24; //this takes up 16+8
  165. break;
  166. case GFXSCT_Float3x3:
  167. csize = 44; //This takes up 16+16+12
  168. break;
  169. case GFXSCT_Float4x3:
  170. csize = 48;
  171. break;
  172. default:
  173. AssertFatal(false, "Unhandled case!");
  174. return;
  175. break;
  176. }
  177. // Loop through and copy
  178. bool ret = false;
  179. U8* currDestPointer = buf + constDesc.offset;
  180. const U8* currSourcePointer = static_cast<const U8*>(data);
  181. const U8* endData = currSourcePointer + inSize;
  182. while (currSourcePointer < endData)
  183. {
  184. if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
  185. {
  186. dMemcpy(currDestPointer, currSourcePointer, csize);
  187. ret = true;
  188. }
  189. currDestPointer += csize;
  190. currSourcePointer += sizeof(MatrixF);
  191. }
  192. }
  193. }
  194. void GFXD3D11ShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const U32 inSize, const void* data)
  195. {
  196. AssertFatal(handle, "GFXD3D11ShaderConstBuffer::internalSet - Handle is NULL!");
  197. AssertFatal(handle->isValid(), "GFXD3D11ShaderConstBuffer::internalSet - Handle is not valid!");
  198. AssertFatal(dynamic_cast<GFXD3D11ShaderConstHandle*>(handle), "GFXD3D11ShaderConstBuffer::internalSet - Incorrect const buffer type");
  199. GFXD3D11ShaderConstHandle* _dxHandle = static_cast<GFXD3D11ShaderConstHandle*>(handle);
  200. AssertFatal(mShader == _dxHandle->mShader, "GFXD3D11ShaderConstBuffer::internalSet - Should only set handles which are owned by our shader");
  201. S32 size = inSize;
  202. for (U32 i = VERTEX_SHADER; i <= COMPUTE_SHADER; i = GFXShaderStage(i << 1))
  203. {
  204. if (_dxHandle->mStageFlags & i)
  205. {
  206. S32 shaderStageID = -1; // Initialize to -1 (bit not found)
  207. for (int j = 0; j < sizeof(S32) * 8; ++j) {
  208. if (i & (1 << j)) {
  209. shaderStageID = j;
  210. break;
  211. }
  212. }
  213. GFXShaderConstDesc constDesc = _dxHandle->getDesc((GFXShaderStage)i);
  214. BufferKey bufDesc(constDesc.bindPoint, shaderStageID);
  215. U8* basePointer = mBufferMap[bufDesc].data;
  216. if (_dxHandle->mInstancingConstant)
  217. {
  218. dMemcpy(mInstPtr + constDesc.offset, data, size);
  219. return;
  220. }
  221. switch (constDesc.constType)
  222. {
  223. case GFXSCT_Float2x2:
  224. case GFXSCT_Float3x3:
  225. case GFXSCT_Float4x3:
  226. case GFXSCT_Float4x4:
  227. setMatrix(constDesc, size, data, basePointer);
  228. return;
  229. break;
  230. // TODO add other AlignedVector here
  231. case GFXSCT_Float2:
  232. if (size > sizeof(Point2F))
  233. size = constDesc.size;
  234. break;
  235. default:
  236. break;
  237. }
  238. if (dMemcmp(basePointer + constDesc.offset, data, size) != 0)
  239. {
  240. dMemcpy(basePointer + constDesc.offset, data, size);
  241. }
  242. }
  243. }
  244. }
  245. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv)
  246. {
  247. internalSet(handle, sizeof(F32), &fv);
  248. }
  249. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2F& fv)
  250. {
  251. internalSet(handle, sizeof(Point2F), &fv);
  252. }
  253. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3F& fv)
  254. {
  255. internalSet(handle, sizeof(Point3F), &fv);
  256. }
  257. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4F& fv)
  258. {
  259. internalSet(handle, sizeof(Point4F), &fv);
  260. }
  261. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv)
  262. {
  263. internalSet(handle, sizeof(PlaneF), &fv);
  264. }
  265. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv)
  266. {
  267. internalSet(handle, sizeof(Point4F), &fv);
  268. }
  269. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 fv)
  270. {
  271. // This is the only type that is allowed to be used
  272. // with a sampler shader constant type, but it is only
  273. // allowed to be set from GLSL.
  274. //
  275. // So we ignore it here... all other cases will assert.
  276. //
  277. if (((GFXD3D11ShaderConstHandle*)handle)->isSampler())
  278. return;
  279. internalSet(handle, sizeof(S32), &fv);
  280. }
  281. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2I& fv)
  282. {
  283. internalSet(handle, sizeof(Point2I), &fv);
  284. }
  285. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3I& fv)
  286. {
  287. internalSet(handle, sizeof(Point3I), &fv);
  288. }
  289. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv)
  290. {
  291. internalSet(handle, sizeof(Point4I), &fv);
  292. }
  293. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv)
  294. {
  295. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  296. }
  297. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv)
  298. {
  299. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  300. }
  301. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv)
  302. {
  303. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  304. }
  305. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
  306. {
  307. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  308. }
  309. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv)
  310. {
  311. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  312. }
  313. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv)
  314. {
  315. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  316. }
  317. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv)
  318. {
  319. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  320. }
  321. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv)
  322. {
  323. internalSet(handle, fv.getElementSize() * fv.size(), fv.getBuffer());
  324. }
  325. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType)
  326. {
  327. AssertFatal(handle, "Handle is NULL!");
  328. AssertFatal(handle->isValid(), "Handle is not valid!");
  329. AssertFatal(static_cast<GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!");
  330. GFXD3D11ShaderConstHandle* _dxHandle = static_cast<GFXD3D11ShaderConstHandle*>(handle);
  331. AssertFatal(!_dxHandle->isSampler(), "Handle is sampler constant!");
  332. AssertFatal(_dxHandle->mShader == mShader, "Mismatched shaders!");
  333. MatrixF transposed;
  334. if (matrixType == GFXSCT_Float4x3)
  335. {
  336. transposed = mat;
  337. }
  338. else
  339. {
  340. mat.transposeTo(transposed);
  341. }
  342. if (_dxHandle->mInstancingConstant)
  343. {
  344. GFXShaderConstDesc constDesc = _dxHandle->getDesc(GFXShaderStage::PIXEL_SHADER);
  345. if (matrixType == GFXSCT_Float4x4)
  346. dMemcpy(mInstPtr + constDesc.offset, mat, sizeof(mat));
  347. // TODO: Support 3x3 and 2x2 matricies?
  348. return;
  349. }
  350. internalSet(handle, sizeof(MatrixF), &transposed);
  351. }
  352. void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
  353. {
  354. AssertFatal(handle, "Handle is NULL!");
  355. AssertFatal(handle->isValid(), "Handle is not valid!");
  356. AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!");
  357. const GFXD3D11ShaderConstHandle* _dxHandle = static_cast<const GFXD3D11ShaderConstHandle*>(handle);
  358. AssertFatal(!_dxHandle->isSampler(), "Handle is sampler constant!");
  359. AssertFatal(_dxHandle->mShader == mShader, "Mismatched shaders!");
  360. static Vector<MatrixF> transposed;
  361. if (arraySize > transposed.size())
  362. transposed.setSize(arraySize);
  363. if (matrixType == GFXSCT_Float4x3)
  364. {
  365. dMemcpy(transposed.address(), mat, arraySize * sizeof(MatrixF));
  366. }
  367. else
  368. {
  369. for (U32 i = 0; i < arraySize; i++)
  370. mat[i].transposeTo(transposed[i]);
  371. }
  372. // TODO: Maybe support this in the future?
  373. if (_dxHandle->mInstancingConstant)
  374. return;
  375. internalSet(handle, sizeof(MatrixF) * arraySize, transposed.begin());
  376. }
  377. const String GFXD3D11ShaderConstBuffer::describeSelf() const
  378. {
  379. String ret;
  380. ret = String(" GFXD3D11ShaderConstBuffer\n");
  381. return ret;
  382. }
  383. void GFXD3D11ShaderConstBuffer::addBuffer(const GFXShaderConstDesc desc)
  384. {
  385. S32 shaderStageID = -1; // Initialize to -1 (bit not found)
  386. for (int i = 0; i < sizeof(S32) * 8; ++i) {
  387. if (desc.shaderStage & (1 << i)) {
  388. shaderStageID = i;
  389. break;
  390. }
  391. }
  392. // no shaderstage defined? cannot be!!!
  393. if (shaderStageID == -1)
  394. {
  395. AssertFatal(false, "DX Const buffer requires a shaderStage flag.");
  396. }
  397. const BufferKey bufKey(desc.bindPoint, shaderStageID);
  398. // doesnt matter if its already added.
  399. U8* buf = new U8[desc.size];
  400. dMemset(buf, 0, desc.size);
  401. mBufferMap[bufKey].data = buf;
  402. mBufferMap[bufKey].size = desc.size;
  403. mBufferMap[bufKey].isDirty = true;
  404. mBoundBuffers[(U32)shaderStageID][desc.bindPoint] = D3D11->getDeviceBuffer(desc);
  405. }
  406. void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
  407. {
  408. PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate);
  409. BufferRange bufRanges[6];
  410. for (BufferMap::Iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i)
  411. {
  412. const BufferKey thisBufferDesc = i->key;
  413. ConstantBuffer thisBuff = i->value;
  414. if (prevShaderBuffer && prevShaderBuffer != this)
  415. {
  416. const ConstantBuffer prevBuffer = prevShaderBuffer->mBufferMap[i->key];
  417. if (prevBuffer.data && !prevBuffer.isDirty)
  418. {
  419. if (prevBuffer.size != thisBuff.size)
  420. {
  421. thisBuff.isDirty = true;
  422. }
  423. else
  424. {
  425. if (dMemcmp(prevBuffer.data, thisBuff.data, thisBuff.size) != 0)
  426. {
  427. thisBuff.isDirty = true;
  428. }
  429. else
  430. {
  431. thisBuff.isDirty = false;
  432. }
  433. }
  434. }
  435. else
  436. {
  437. thisBuff.isDirty = true;
  438. }
  439. }
  440. else
  441. {
  442. thisBuff.isDirty = true;
  443. }
  444. if (thisBuff.data && thisBuff.isDirty)
  445. {
  446. D3D11DEVICECONTEXT->UpdateSubresource(mBoundBuffers[thisBufferDesc.key2][thisBufferDesc.key1], 0, NULL, thisBuff.data, thisBuff.size, 0);
  447. bufRanges[thisBufferDesc.key2].addSlot(thisBufferDesc.key1);
  448. }
  449. }
  450. if (mShader->mVertShader && bufRanges[0].isValid())
  451. {
  452. const U32 bufStartSlot = bufRanges[0].mBufMin;
  453. const U32 numBufs = bufRanges[0].mBufMax - bufRanges[0].mBufMin + 1;
  454. ID3D11Buffer** vsBuffers = mBoundBuffers[0] + bufStartSlot;
  455. D3D11DEVICECONTEXT->VSSetConstantBuffers(bufStartSlot, numBufs, vsBuffers);
  456. }
  457. if (mShader->mPixShader && bufRanges[1].isValid())
  458. {
  459. const U32 bufStartSlot = bufRanges[1].mBufMin;
  460. const U32 numBufs = bufRanges[1].mBufMax - bufRanges[1].mBufMin + 1;
  461. ID3D11Buffer** psBuffers = mBoundBuffers[1] + bufStartSlot;
  462. D3D11DEVICECONTEXT->PSSetConstantBuffers(bufStartSlot, numBufs, psBuffers);
  463. }
  464. if (mShader->mGeoShader && bufRanges[2].isValid())
  465. {
  466. const U32 bufStartSlot = bufRanges[2].mBufMin;
  467. const U32 numBufs = bufRanges[2].mBufMax - bufRanges[2].mBufMin + 1;
  468. ID3D11Buffer** psBuffers = mBoundBuffers[2] + bufStartSlot;
  469. D3D11DEVICECONTEXT->GSSetConstantBuffers(bufStartSlot, numBufs, psBuffers);
  470. }
  471. mWasLost = false;
  472. }
  473. void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
  474. {
  475. AssertFatal( shader == mShader, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
  476. for (auto& pair : mBufferMap) {
  477. delete[] pair.value.data;
  478. }
  479. mBufferMap.clear(); // Clear the map
  480. for (GFXD3D11Shader::BufferMap::Iterator i = shader->mBuffers.begin(); i != shader->mBuffers.end(); ++i)
  481. {
  482. // add our buffer descriptions to the full const buffer.
  483. this->addBuffer(i->value);
  484. }
  485. // Set the lost state.
  486. mWasLost = true;
  487. }
  488. //------------------------------------------------------------------------------
  489. GFXD3D11Shader::GFXD3D11Shader()
  490. {
  491. VECTOR_SET_ASSOCIATION( mShaderConsts );
  492. AssertFatal(D3D11DEVICE, "Invalid device for shader.");
  493. mVertShader = NULL;
  494. mPixShader = NULL;
  495. mGeoShader = NULL;
  496. if( smD3DInclude == NULL )
  497. smD3DInclude = new gfxD3D11Include;
  498. }
  499. //------------------------------------------------------------------------------
  500. GFXD3D11Shader::~GFXD3D11Shader()
  501. {
  502. for (auto& pair : mHandles) {
  503. if (pair.value != nullptr) {
  504. delete pair.value;
  505. pair.value = nullptr;
  506. }
  507. }
  508. mHandles.clear();
  509. // release shaders
  510. SAFE_RELEASE(mVertShader);
  511. SAFE_RELEASE(mPixShader);
  512. SAFE_RELEASE(mGeoShader);
  513. //maybe add SAFE_RELEASE(mVertexCode) ?
  514. }
  515. bool GFXD3D11Shader::_init()
  516. {
  517. PROFILE_SCOPE( GFXD3D11Shader_Init );
  518. SAFE_RELEASE(mVertShader);
  519. SAFE_RELEASE(mPixShader);
  520. SAFE_RELEASE(mGeoShader);
  521. // Create the macro array including the system wide macros.
  522. const U32 macroCount = smGlobalMacros.size() + mMacros.size() + 2;
  523. FrameTemp<D3D_SHADER_MACRO> d3dMacros( macroCount );
  524. for ( U32 i=0; i < smGlobalMacros.size(); i++ )
  525. {
  526. d3dMacros[i].Name = smGlobalMacros[i].name.c_str();
  527. d3dMacros[i].Definition = smGlobalMacros[i].value.c_str();
  528. }
  529. for ( U32 i=0; i < mMacros.size(); i++ )
  530. {
  531. d3dMacros[i+smGlobalMacros.size()].Name = mMacros[i].name.c_str();
  532. d3dMacros[i+smGlobalMacros.size()].Definition = mMacros[i].value.c_str();
  533. }
  534. d3dMacros[macroCount - 2].Name = "TORQUE_SM";
  535. d3dMacros[macroCount - 2].Definition = D3D11->getShaderModel().c_str();
  536. memset(&d3dMacros[macroCount - 1], 0, sizeof(D3D_SHADER_MACRO));
  537. mShaderConsts.clear();
  538. mSamplerDescriptions.clear();
  539. if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, GFXShaderStage::VERTEX_SHADER, d3dMacros) )
  540. return false;
  541. if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, GFXShaderStage::PIXEL_SHADER, d3dMacros))
  542. return false;
  543. if (!mGeometryFile.isEmpty())
  544. {
  545. if (!_compileShader(mGeometryFile, GFXShaderStage::GEOMETRY_SHADER, d3dMacros))
  546. return false;
  547. }
  548. // Mark all existing handles as invalid.
  549. // Those that are found when parsing the descriptions will then be marked valid again.
  550. for (auto& pair : mHandles) {
  551. pair.value->clear();
  552. }
  553. _buildShaderConstantHandles();
  554. // Notify any existing buffers that the buffer
  555. // layouts have changed and they need to update.
  556. Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
  557. for ( ; biter != mActiveBuffers.end(); biter++ )
  558. ((GFXD3D11ShaderConstBuffer*)(*biter))->onShaderReload( this );
  559. return true;
  560. }
  561. bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
  562. GFXShaderStage shaderStage,
  563. const D3D_SHADER_MACRO *defines)
  564. {
  565. PROFILE_SCOPE( GFXD3D11Shader_CompileShader );
  566. using namespace Torque;
  567. HRESULT res = E_FAIL;
  568. ID3DBlob* code = NULL;
  569. ID3DBlob* errorBuff = NULL;
  570. ID3D11ShaderReflection* reflectionTable = NULL;
  571. #ifdef TORQUE_GFX_VISUAL_DEBUG //for use with NSight, GPU Perf studio, VS graphics debugger
  572. U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
  573. #elif defined(TORQUE_DEBUG) //debug build
  574. U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
  575. #else //release build
  576. U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3;
  577. #endif
  578. #ifdef D3D11_DEBUG_SPEW
  579. Con::printf( "Compiling Shader: '%s'", filePath.getFullPath().c_str() );
  580. #endif
  581. // Is it an HLSL shader?
  582. if(filePath.getExtension().equal("hlsl", String::NoCase))
  583. {
  584. // Set this so that the D3DInclude::Open will have this
  585. // information for relative paths.
  586. smD3DInclude->setPath(filePath.getRootAndPath());
  587. FileStream s;
  588. if (!s.open(filePath, Torque::FS::File::Read))
  589. {
  590. AssertISV(false, avar("GFXD3D11Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str()));
  591. if ( smLogErrors )
  592. Con::errorf( "GFXD3D11Shader::_compileShader - Failed to open shader file '%s'.", filePath.getFullPath().c_str() );
  593. return false;
  594. }
  595. // Convert the path which might have virtualized
  596. // mount paths to a real file system path.
  597. Torque::Path realPath;
  598. if (!FS::GetFSPath( filePath, realPath))
  599. realPath = filePath;
  600. U32 bufSize = s.getStreamSize();
  601. FrameAllocatorMarker fam;
  602. char *buffer = NULL;
  603. buffer = (char*)fam.alloc(bufSize + 1);
  604. s.read(bufSize, buffer);
  605. buffer[bufSize] = 0;
  606. String target;
  607. switch (shaderStage)
  608. {
  609. case VERTEX_SHADER:
  610. target = D3D11->getVertexShaderTarget();
  611. break;
  612. case PIXEL_SHADER:
  613. target = D3D11->getPixelShaderTarget();
  614. break;
  615. case GEOMETRY_SHADER:
  616. target = D3D11->getGeometryShaderTarget();
  617. break;
  618. case DOMAIN_SHADER:
  619. break;
  620. case HULL_SHADER:
  621. break;
  622. case COMPUTE_SHADER:
  623. break;
  624. default:
  625. break;
  626. }
  627. res = D3DCompile(buffer, bufSize, realPath.getFullPath().c_str(), defines, smD3DInclude, "main", target, flags, 0, &code, &errorBuff);
  628. }
  629. if(errorBuff)
  630. {
  631. // remove \n at end of buffer
  632. U8 *buffPtr = (U8*) errorBuff->GetBufferPointer();
  633. U32 len = dStrlen( (const char*) buffPtr );
  634. buffPtr[len-1] = '\0';
  635. if(FAILED(res))
  636. {
  637. if(smLogErrors)
  638. Con::errorf("failed to compile shader: %s", buffPtr);
  639. }
  640. else
  641. {
  642. if(smLogWarnings)
  643. Con::errorf("shader compiled with warning(s): %s", buffPtr);
  644. }
  645. }
  646. else if (code == NULL && smLogErrors)
  647. Con::errorf( "GFXD3D11Shader::_compileShader - no compiled code produced; possibly missing file '%s'.", filePath.getFullPath().c_str() );
  648. AssertISV(SUCCEEDED(res), "Unable to compile shader!");
  649. if(code != NULL)
  650. {
  651. switch (shaderStage)
  652. {
  653. case VERTEX_SHADER:
  654. res = D3D11DEVICE->CreateVertexShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mVertShader);
  655. break;
  656. case PIXEL_SHADER:
  657. res = D3D11DEVICE->CreatePixelShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mPixShader);
  658. break;
  659. case GEOMETRY_SHADER:
  660. res = D3D11DEVICE->CreateGeometryShader(code->GetBufferPointer(), code->GetBufferSize(), NULL, &mGeoShader);
  661. break;
  662. case DOMAIN_SHADER:
  663. break;
  664. case HULL_SHADER:
  665. break;
  666. case COMPUTE_SHADER:
  667. break;
  668. default:
  669. break;
  670. }
  671. if (FAILED(res))
  672. {
  673. AssertFatal(false, "D3D11Shader::_compilershader- failed to create shader");
  674. }
  675. if(res == S_OK)
  676. {
  677. HRESULT reflectionResult = D3DReflect(code->GetBufferPointer(), code->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&reflectionTable);
  678. if(FAILED(reflectionResult))
  679. AssertFatal(false, "D3D11Shader::_compilershader - Failed to get shader reflection table interface");
  680. }
  681. if(res == S_OK)
  682. _getShaderConstants(reflectionTable, shaderStage);
  683. if(FAILED(res) && smLogErrors)
  684. Con::errorf("GFXD3D11Shader::_compileShader - Unable to create shader for '%s'.", filePath.getFullPath().c_str());
  685. }
  686. //bool result = code && SUCCEEDED(res) && HasValidConstants;
  687. bool result = code && SUCCEEDED(res);
  688. #ifdef TORQUE_DEBUG
  689. String shader;
  690. switch (shaderStage)
  691. {
  692. case VERTEX_SHADER:
  693. shader = mVertexFile.getFileName();
  694. mVertShader->SetPrivateData(WKPDID_D3DDebugObjectName, shader.size(), shader.c_str());
  695. break;
  696. case PIXEL_SHADER:
  697. shader = mPixelFile.getFileName();
  698. mPixShader->SetPrivateData(WKPDID_D3DDebugObjectName, shader.size(), shader.c_str());
  699. break;
  700. case GEOMETRY_SHADER:
  701. shader = mGeometryFile.getFileName();
  702. mGeoShader->SetPrivateData(WKPDID_D3DDebugObjectName, shader.size(), shader.c_str());
  703. break;
  704. case DOMAIN_SHADER:
  705. break;
  706. case HULL_SHADER:
  707. break;
  708. case COMPUTE_SHADER:
  709. break;
  710. default:
  711. break;
  712. }
  713. #endif
  714. SAFE_RELEASE(code);
  715. SAFE_RELEASE(reflectionTable);
  716. SAFE_RELEASE(errorBuff);
  717. return result;
  718. }
  719. void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection* refTable,
  720. GFXShaderStage shaderStage)
  721. {
  722. PROFILE_SCOPE(GFXD3D11Shader_GetShaderConstants);
  723. AssertFatal(refTable, "NULL constant table not allowed, is this an assembly shader?");
  724. D3D11_SHADER_DESC shaderDesc;
  725. if (refTable->GetDesc(&shaderDesc) != S_OK)
  726. {
  727. AssertFatal(false, "Shader Reflection table unable to be created");
  728. }
  729. // we loop through and account for the most common data types.
  730. for (U32 i = 0; i < shaderDesc.ConstantBuffers; i++)
  731. {
  732. GFXShaderConstDesc desc;
  733. ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByIndex(i);
  734. D3D11_SHADER_BUFFER_DESC constantBufferDesc;
  735. if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
  736. {
  737. desc.name = String(constantBufferDesc.Name);
  738. desc.size = constantBufferDesc.Size;
  739. desc.constType = GFXSCT_ConstBuffer;
  740. desc.shaderStage = shaderStage;
  741. desc.samplerReg = -1;
  742. // get our binding point.
  743. D3D11_SHADER_INPUT_BIND_DESC shaderInputBind;
  744. refTable->GetResourceBindingDescByName(constantBufferDesc.Name, &shaderInputBind);
  745. desc.bindPoint = shaderInputBind.BindPoint;
  746. if (String::compare(desc.name, "$Globals") == 0 || String::compare(desc.name, "$Params") == 0)
  747. {
  748. switch (shaderStage)
  749. {
  750. case VERTEX_SHADER:
  751. desc.name = desc.name + "_" + mVertexFile.getFileName();
  752. break;
  753. case PIXEL_SHADER:
  754. desc.name = desc.name + "_" + mPixelFile.getFileName();
  755. break;
  756. case GEOMETRY_SHADER:
  757. desc.name = desc.name + "_" + mGeometryFile.getFileName();
  758. break;
  759. case DOMAIN_SHADER:
  760. break;
  761. case HULL_SHADER:
  762. break;
  763. case COMPUTE_SHADER:
  764. break;
  765. default:
  766. break;
  767. }
  768. }
  769. mBuffers[desc.name] = desc;
  770. // now loop vars and add them to mShaderConsts.
  771. for (U32 j = 0; j < constantBufferDesc.Variables; j++)
  772. {
  773. ID3D11ShaderReflectionVariable* bufferVar = constantBuffer->GetVariableByIndex(j);
  774. D3D11_SHADER_VARIABLE_DESC shaderVarDesc;
  775. bufferVar->GetDesc(&shaderVarDesc);
  776. D3D11_SHADER_TYPE_DESC shaderTypeDesc;
  777. bufferVar->GetType()->GetDesc(&shaderTypeDesc);
  778. if (shaderTypeDesc.Class == D3D_SVC_STRUCT)
  779. {
  780. // we gotta loop through its variables =/ add support in future. for now continue so it skips.
  781. // no idea how to handle arrays of structs....
  782. /*for (U32 j = 0; j < shaderTypeDesc.Members; j++)
  783. {
  784. GFXShaderConstDesc memVarDesc;
  785. ID3D11ShaderReflectionType* memType = bufferVar->GetType()->GetMemberTypeByIndex(j);
  786. D3D11_SHADER_TYPE_DESC memTypeDesc;
  787. memType->GetDesc(&memTypeDesc);
  788. memVarDesc.name = String(shaderVarDesc.Name) + "." + String(memTypeDesc.Name);
  789. if (memVarDesc.name.find("$") != 0)
  790. memVarDesc.name = String::ToString("$%s", memVarDesc.name.c_str());
  791. #ifdef D3D11_DEBUG_SPEW
  792. Con::printf("Variable Name %s:, offset: %d", memVarDesc.name.c_str(), memVarDesc.Offset);
  793. #endif
  794. }*/
  795. continue;
  796. }
  797. else
  798. {
  799. GFXShaderConstDesc varDesc;
  800. varDesc.name = String(shaderVarDesc.Name);
  801. if (varDesc.name.find("$") != 0)
  802. varDesc.name = String::ToString("$%s", varDesc.name.c_str());
  803. // set the bind point to the same as the const buffer.
  804. varDesc.bindPoint = desc.bindPoint;
  805. varDesc.offset = shaderVarDesc.StartOffset;
  806. varDesc.arraySize = mMax(shaderTypeDesc.Elements, 1);
  807. varDesc.size = shaderVarDesc.Size;
  808. varDesc.shaderStage = shaderStage;
  809. varDesc.samplerReg = -1;
  810. varDesc.constType = convertConstType(shaderTypeDesc);
  811. #ifdef D3D11_DEBUG_SPEW
  812. Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", varDesc.name.c_str(), varDesc.offset, varDesc.size, varDesc.arraySize);
  813. #endif
  814. mShaderConsts.push_back(varDesc);
  815. }
  816. }
  817. }
  818. else
  819. {
  820. AssertFatal(false, "Unable to get shader constant description! (may need more elements of constantDesc");
  821. }
  822. }
  823. for (U32 i = 0; i < shaderDesc.BoundResources; i++)
  824. {
  825. GFXShaderConstDesc desc;
  826. D3D11_SHADER_INPUT_BIND_DESC shaderInputBind;
  827. refTable->GetResourceBindingDesc(i, &shaderInputBind);
  828. if (shaderInputBind.Type == D3D_SIT_TEXTURE || shaderInputBind.Type == D3D_SIT_UAV_RWTYPED)
  829. {
  830. // these should return shaderResourceViews and add them to shaderResources.
  831. /*switch (shaderInputBind.Dimension)
  832. {
  833. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1D:
  834. break;
  835. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE1DARRAY:
  836. break;
  837. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2D:
  838. break;
  839. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DARRAY:
  840. break;
  841. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DMS:
  842. break;
  843. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE2DMSARRAY:
  844. break;
  845. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURE3D:
  846. break;
  847. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURECUBE:
  848. break;
  849. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_TEXTURECUBEARRAY:
  850. break;
  851. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_BUFFER:
  852. break;
  853. case D3D_SRV_DIMENSION::D3D_SRV_DIMENSION_BUFFEREX:
  854. break;
  855. default:
  856. break;
  857. }*/
  858. }
  859. else if (shaderInputBind.Type == D3D_SIT_SAMPLER)
  860. {
  861. // Prepend a "$" if it doesn't exist. Just to make things consistent.
  862. desc.name = String(shaderInputBind.Name);
  863. if (desc.name.find("$") != 0)
  864. desc.name = String::ToString("$%s", desc.name.c_str());
  865. desc.constType = GFXSCT_Sampler;
  866. desc.samplerReg = shaderInputBind.BindPoint;
  867. desc.bindPoint = -1;
  868. desc.shaderStage = shaderStage;
  869. desc.arraySize = shaderInputBind.BindCount;
  870. mSamplerDescriptions.push_back(desc);
  871. }
  872. else if (shaderInputBind.Type == D3D_SIT_UAV_RWSTRUCTURED ||
  873. shaderInputBind.Type == D3D_SIT_UAV_RWBYTEADDRESS ||
  874. shaderInputBind.Type == D3D_SIT_UAV_APPEND_STRUCTURED ||
  875. shaderInputBind.Type == D3D_SIT_UAV_CONSUME_STRUCTURED ||
  876. shaderInputBind.Type == D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER)
  877. {
  878. // these should return an unorderedAccessViews and add them to shaderResources.
  879. }
  880. else if (shaderInputBind.Type == D3D_SIT_STRUCTURED ||
  881. shaderInputBind.Type == D3D_SIT_BYTEADDRESS)
  882. {
  883. // these should return shaderResourceViews and add them to shaderResources.
  884. }
  885. }
  886. }
  887. GFXShaderConstType GFXD3D11Shader::convertConstType(const D3D11_SHADER_TYPE_DESC typeDesc)
  888. {
  889. if (typeDesc.Class == D3D_SVC_SCALAR || typeDesc.Class == D3D_SVC_VECTOR)
  890. {
  891. switch (typeDesc.Type)
  892. {
  893. case D3D_SVT_BOOL:
  894. return (GFXShaderConstType)((U32)GFXSCT_Bool + typeDesc.Columns - 1);
  895. break;
  896. case D3D_SVT_INT:
  897. return (GFXShaderConstType)((U32)GFXSCT_Int + typeDesc.Columns - 1);
  898. break;
  899. case D3D_SVT_FLOAT:
  900. return (GFXShaderConstType)((U32)GFXSCT_Float + typeDesc.Columns - 1);
  901. break;
  902. case D3D_SVT_UINT:
  903. return (GFXShaderConstType)((U32)GFXSCT_UInt + typeDesc.Columns - 1);
  904. break;
  905. default:
  906. AssertFatal(false, "Unknown shader constant class enum, maybe you could add it?");
  907. break;
  908. }
  909. }
  910. else if (typeDesc.Class == D3D_SVC_MATRIX_COLUMNS || typeDesc.Class == D3D_SVC_MATRIX_ROWS)
  911. {
  912. if (typeDesc.Type != D3D_SVT_FLOAT)
  913. {
  914. AssertFatal(false, "Only Float matrices are supported for now. Support for other types needs to be added.");
  915. }
  916. switch (typeDesc.Rows)
  917. {
  918. case 3:
  919. return typeDesc.Columns == 4 ? GFXSCT_Float3x4 : GFXSCT_Float3x3;
  920. break;
  921. case 4:
  922. return typeDesc.Columns == 3 ? GFXSCT_Float4x3 : GFXSCT_Float4x4;
  923. break;
  924. }
  925. }
  926. return GFXSCT_Uknown;
  927. }
  928. void GFXD3D11Shader::_buildShaderConstantHandles()
  929. {
  930. // loop through all constants, add them to the handle map
  931. // and add the const buffers to the buffer map.
  932. for (U32 i = 0; i < mShaderConsts.size(); i++)
  933. {
  934. GFXD3D11ShaderConstHandle* handle;
  935. GFXShaderConstDesc& desc = mShaderConsts[i];
  936. HandleMap::Iterator j = mHandles.find(desc.name);
  937. // already added? reinit just in case..
  938. // not sure if we need to do anything different with samplers.
  939. if (j != mHandles.end())
  940. {
  941. handle = j->value;
  942. handle->mShader = this;
  943. if((handle->mStageFlags & desc.shaderStage) == 0)
  944. handle->mStageFlags |= (U32)desc.shaderStage;
  945. handle->addDesc(desc.shaderStage, desc);
  946. handle->setValid(true);
  947. }
  948. else
  949. {
  950. handle = new GFXD3D11ShaderConstHandle(this, desc);
  951. mHandles[desc.name] = handle;
  952. }
  953. }
  954. for (U32 j = 0; j < mSamplerDescriptions.size(); j++)
  955. {
  956. const GFXShaderConstDesc& desc = mSamplerDescriptions[j];
  957. AssertFatal(desc.constType == GFXSCT_Sampler ||
  958. desc.constType == GFXSCT_SamplerCube ||
  959. desc.constType == GFXSCT_SamplerCubeArray ||
  960. desc.constType == GFXSCT_SamplerTextureArray,
  961. "GFXD3D11Shader::_buildShaderConstantHandles - Invalid samplerDescription type!");
  962. GFXD3D11ShaderConstHandle* handle;
  963. HandleMap::Iterator k = mHandles.find(desc.name);
  964. // already added? reinit just in case..
  965. // not sure if we need to do anything different with samplers.
  966. if (k != mHandles.end())
  967. {
  968. handle = k->value;
  969. }
  970. else
  971. {
  972. handle = new GFXD3D11ShaderConstHandle(this, desc);
  973. mHandles[desc.name] = handle;
  974. }
  975. handle->mShader = this;
  976. handle->setValid(true);
  977. }
  978. _buildInstancingShaderConstantHandles();
  979. }
  980. void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
  981. {
  982. // If we have no instancing than just return
  983. if (!mInstancingFormat)
  984. return;
  985. U32 offset = 0;
  986. for ( U32 i=0; i < mInstancingFormat->getElementCount(); i++ )
  987. {
  988. const GFXVertexElement &element = mInstancingFormat->getElement( i );
  989. String constName = String::ToString( "$%s", element.getSemantic().c_str() );
  990. GFXD3D11ShaderConstHandle *handle;
  991. HandleMap::Iterator j = mHandles.find( constName );
  992. GFXShaderConstDesc desc;
  993. desc.name = constName;
  994. desc.offset = offset;
  995. switch (element.getType())
  996. {
  997. case GFXDeclType_Float4:
  998. desc.constType = GFXSCT_Float4;
  999. break;
  1000. default:
  1001. desc.constType = GFXSCT_Float;
  1002. break;
  1003. }
  1004. desc.shaderStage = GFXShaderStage::PIXEL_SHADER;
  1005. desc.samplerReg = -1;
  1006. desc.size = 0;
  1007. desc.arraySize = 1;
  1008. if ( j != mHandles.end() )
  1009. handle = j->value;
  1010. else
  1011. {
  1012. handle = new GFXD3D11ShaderConstHandle(this, desc);
  1013. mHandles[ constName ] = handle;
  1014. }
  1015. handle->mShader = this;
  1016. handle->setValid( true );
  1017. handle->mInstancingConstant = true;
  1018. // If this is a matrix we will have 2 or 3 more of these
  1019. // semantics with the same name after it.
  1020. for ( ; i < mInstancingFormat->getElementCount(); i++ )
  1021. {
  1022. const GFXVertexElement &nextElement = mInstancingFormat->getElement( i );
  1023. if ( nextElement.getSemantic() != element.getSemantic() )
  1024. {
  1025. i--;
  1026. break;
  1027. }
  1028. offset += nextElement.getSizeInBytes();
  1029. }
  1030. }
  1031. }
  1032. GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
  1033. {
  1034. GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this);
  1035. for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); ++i)
  1036. {
  1037. // add our buffer descriptions to the full const buffer.
  1038. buffer->addBuffer(i->value);
  1039. }
  1040. mActiveBuffers.push_back( buffer );
  1041. buffer->registerResourceWithDevice(getOwningDevice());
  1042. return buffer;
  1043. }
  1044. /// Returns a shader constant handle for name, if the variable doesn't exist NULL is returned.
  1045. GFXShaderConstHandle* GFXD3D11Shader::getShaderConstHandle(const String& name)
  1046. {
  1047. HandleMap::Iterator i = mHandles.find(name);
  1048. if ( i != mHandles.end() )
  1049. {
  1050. return i->value;
  1051. }
  1052. else
  1053. {
  1054. GFXD3D11ShaderConstHandle *handle = new GFXD3D11ShaderConstHandle(this);
  1055. handle->setValid( false );
  1056. mHandles[name] = handle;
  1057. return handle;
  1058. }
  1059. }
  1060. GFXShaderConstHandle* GFXD3D11Shader::findShaderConstHandle(const String& name)
  1061. {
  1062. HandleMap::Iterator i = mHandles.find(name);
  1063. if(i != mHandles.end())
  1064. return i->value;
  1065. else
  1066. {
  1067. return NULL;
  1068. }
  1069. }
  1070. const Vector<GFXShaderConstDesc>& GFXD3D11Shader::getShaderConstDesc() const
  1071. {
  1072. return mShaderConsts;
  1073. }
  1074. U32 GFXD3D11Shader::getAlignmentValue(const GFXShaderConstType constType) const
  1075. {
  1076. const U32 mRowSizeF = 16;
  1077. const U32 mRowSizeI = 16;
  1078. switch (constType)
  1079. {
  1080. case GFXSCT_Float :
  1081. case GFXSCT_Float2 :
  1082. case GFXSCT_Float3 :
  1083. case GFXSCT_Float4 :
  1084. return mRowSizeF;
  1085. break;
  1086. // Matrices
  1087. case GFXSCT_Float2x2 :
  1088. return mRowSizeF * 2;
  1089. break;
  1090. case GFXSCT_Float3x3 :
  1091. return mRowSizeF * 3;
  1092. break;
  1093. case GFXSCT_Float4x3:
  1094. return mRowSizeF * 3;
  1095. break;
  1096. case GFXSCT_Float4x4 :
  1097. return mRowSizeF * 4;
  1098. break;
  1099. //// Scalar
  1100. case GFXSCT_Int :
  1101. case GFXSCT_Int2 :
  1102. case GFXSCT_Int3 :
  1103. case GFXSCT_Int4 :
  1104. return mRowSizeI;
  1105. break;
  1106. default:
  1107. AssertFatal(false, "Unsupported type!");
  1108. return 0;
  1109. break;
  1110. }
  1111. }
  1112. void GFXD3D11Shader::zombify()
  1113. {
  1114. // Shaders don't need zombification
  1115. }
  1116. void GFXD3D11Shader::resurrect()
  1117. {
  1118. // Shaders are never zombies, and therefore don't have to be brought back.
  1119. }