OgreD3D9Texture.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976
  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. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreD3D9Texture.h"
  25. #include "OgreD3D9HardwarePixelBuffer.h"
  26. #include "OgreException.h"
  27. #include "OgreStringConverter.h"
  28. #include "OgreBitwise.h"
  29. #include "OgreD3D9Mappings.h"
  30. #include "OgreD3D9RenderSystem.h"
  31. #include "OgreD3D9TextureManager.h"
  32. #include "OgreD3D9Device.h"
  33. #include "OgreD3D9DeviceManager.h"
  34. #include "OgreD3D9ResourceManager.h"
  35. #include "CmRenderSystemManager.h"
  36. namespace Ogre
  37. {
  38. /****************************************************************************************/
  39. D3D9Texture::D3D9Texture()
  40. :Texture(),
  41. mD3DPool(D3DPOOL_MANAGED),
  42. mDynamicTextures(false),
  43. mHwGammaReadSupported(false),
  44. mHwGammaWriteSupported(false),
  45. mFSAAType(D3DMULTISAMPLE_NONE),
  46. mFSAAQuality(0)
  47. {
  48. }
  49. /****************************************************************************************/
  50. D3D9Texture::~D3D9Texture()
  51. {
  52. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  53. // have to call this here reather than in Resource destructor
  54. // since calling virtual methods in base destructors causes crash
  55. freeInternalResources();
  56. // Free memory allocated per device.
  57. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
  58. while (it != mMapDeviceToTextureResources.end())
  59. {
  60. TextureResources* textureResource = it->second;
  61. SAFE_DELETE(textureResource);
  62. ++it;
  63. }
  64. mMapDeviceToTextureResources.clear();
  65. mSurfaceList.clear();
  66. }
  67. /****************************************************************************************/
  68. void D3D9Texture::copyToTexture(TexturePtr& target)
  69. {
  70. // check if this & target are the same format and type
  71. // blitting from or to cube textures is not supported yet
  72. if (target->getUsage() != getUsage() ||
  73. target->getTextureType() != getTextureType())
  74. {
  75. OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
  76. "Src. and dest. textures must be of same type and must have the same usage !!!",
  77. "D3D9Texture::copyToTexture" );
  78. }
  79. HRESULT hr;
  80. D3D9Texture *other;
  81. // get the target
  82. other = reinterpret_cast< D3D9Texture * >( target.get() );
  83. // target rectangle (whole surface)
  84. RECT dstRC = {0, 0, static_cast<LONG>(other->getWidth()), static_cast<LONG>(other->getHeight())};
  85. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
  86. while (it != mMapDeviceToTextureResources.end())
  87. {
  88. TextureResources* srcTextureResource = it->second;
  89. TextureResources* dstTextureResource = other->getTextureResources(it->first);
  90. // do it plain for normal texture
  91. if (getTextureType() == TEX_TYPE_2D &&
  92. srcTextureResource->pNormTex &&
  93. dstTextureResource->pNormTex)
  94. {
  95. // get our source surface
  96. IDirect3DSurface9 *pSrcSurface = 0;
  97. if( FAILED( hr = srcTextureResource->pNormTex->GetSurfaceLevel(0, &pSrcSurface) ) )
  98. {
  99. String msg = DXGetErrorDescription(hr);
  100. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  101. }
  102. // get our target surface
  103. IDirect3DSurface9 *pDstSurface = 0;
  104. if( FAILED( hr = dstTextureResource->pNormTex->GetSurfaceLevel(0, &pDstSurface) ) )
  105. {
  106. String msg = DXGetErrorDescription(hr);
  107. SAFE_RELEASE(pSrcSurface);
  108. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  109. }
  110. // do the blit, it's called StretchRect in D3D9 :)
  111. if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) )
  112. {
  113. String msg = DXGetErrorDescription(hr);
  114. SAFE_RELEASE(pSrcSurface);
  115. SAFE_RELEASE(pDstSurface);
  116. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  117. }
  118. // release temp. surfaces
  119. SAFE_RELEASE(pSrcSurface);
  120. SAFE_RELEASE(pDstSurface);
  121. }
  122. else if (getTextureType() == TEX_TYPE_CUBE_MAP &&
  123. srcTextureResource->pCubeTex &&
  124. dstTextureResource->pCubeTex)
  125. {
  126. // blit to 6 cube faces
  127. for (size_t face = 0; face < 6; face++)
  128. {
  129. // get our source surface
  130. IDirect3DSurface9 *pSrcSurface = 0;
  131. if( FAILED( hr =srcTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pSrcSurface) ) )
  132. {
  133. String msg = DXGetErrorDescription(hr);
  134. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  135. }
  136. // get our target surface
  137. IDirect3DSurface9 *pDstSurface = 0;
  138. if( FAILED( hr = dstTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pDstSurface) ) )
  139. {
  140. String msg = DXGetErrorDescription(hr);
  141. SAFE_RELEASE(pSrcSurface);
  142. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  143. }
  144. // do the blit, it's called StretchRect in D3D9 :)
  145. if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) )
  146. {
  147. String msg = DXGetErrorDescription(hr);
  148. SAFE_RELEASE(pSrcSurface);
  149. SAFE_RELEASE(pDstSurface);
  150. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
  151. }
  152. // release temp. surfaces
  153. SAFE_RELEASE(pSrcSurface);
  154. SAFE_RELEASE(pDstSurface);
  155. }
  156. }
  157. else
  158. {
  159. OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED,
  160. "Copy to texture is implemented only for 2D and cube textures !!!",
  161. "D3D9Texture::copyToTexture" );
  162. }
  163. ++it;
  164. }
  165. }
  166. /****************************************************************************************/
  167. void D3D9Texture::loadImpl()
  168. {
  169. if (!mInternalResourcesCreated)
  170. {
  171. // NB: Need to initialise pool to some value other than D3DPOOL_DEFAULT,
  172. // otherwise, if the texture loading failed, it might re-create as empty
  173. // texture when device lost/restore. The actual pool will determine later.
  174. mD3DPool = D3DPOOL_MANAGED;
  175. }
  176. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  177. for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i)
  178. {
  179. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i);
  180. loadImpl(d3d9Device);
  181. }
  182. }
  183. /****************************************************************************************/
  184. void D3D9Texture::loadImpl(IDirect3DDevice9* d3d9Device)
  185. {
  186. if (mUsage & TU_RENDERTARGET)
  187. {
  188. createInternalResourcesImpl(d3d9Device);
  189. return;
  190. }
  191. // TODO PORT - Loading tex from streams not supported
  192. //// Make sure streams prepared.
  193. //if (mLoadedStreams.isNull())
  194. //{
  195. // prepareImpl();
  196. //}
  197. //
  198. //// Set reading positions of loaded streams to the beginning.
  199. //for (uint i = 0; i < mLoadedStreams->size(); ++i)
  200. //{
  201. // MemoryDataStreamPtr curDataStream = (*mLoadedStreams)[i];
  202. // curDataStream->seek(0);
  203. //}
  204. //// only copy is on the stack so well-behaved if exception thrown
  205. //LoadedStreams loadedStreams = mLoadedStreams;
  206. //// load based on tex.type
  207. //switch (getTextureType())
  208. //{
  209. //case TEX_TYPE_1D:
  210. //case TEX_TYPE_2D:
  211. // _loadNormTex(d3d9Device, loadedStreams);
  212. // break;
  213. //case TEX_TYPE_3D:
  214. // _loadVolumeTex(d3d9Device, loadedStreams);
  215. // break;
  216. //case TEX_TYPE_CUBE_MAP:
  217. // _loadCubeTex(d3d9Device, loadedStreams);
  218. // break;
  219. //default:
  220. // OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::loadImpl" );
  221. //}
  222. }
  223. /****************************************************************************************/
  224. void D3D9Texture::prepareImpl()
  225. {
  226. if (mUsage & TU_RENDERTARGET)
  227. {
  228. return;
  229. }
  230. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  231. // TODO PORT - Loading tex from streams not supported
  232. // LoadedStreams loadedStreams;
  233. //// prepare load based on tex.type
  234. //switch (getTextureType())
  235. //{
  236. //case TEX_TYPE_1D:
  237. //case TEX_TYPE_2D:
  238. // loadedStreams = _prepareNormTex();
  239. // break;
  240. //case TEX_TYPE_3D:
  241. // loadedStreams = _prepareVolumeTex();
  242. // break;
  243. //case TEX_TYPE_CUBE_MAP:
  244. // loadedStreams = _prepareCubeTex();
  245. // break;
  246. //default:
  247. // OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::prepareImpl" );
  248. //}
  249. //mLoadedStreams = loadedStreams;
  250. }
  251. /****************************************************************************************/
  252. // TODO PORT - Loading tex from streams not supported
  253. //D3D9Texture::LoadedStreams D3D9Texture::_prepareCubeTex()
  254. //{
  255. // assert(getTextureType() == TEX_TYPE_CUBE_MAP);
  256. // LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
  257. // // DDS load?
  258. // if (getSourceFileType() == "dds")
  259. // {
  260. // // find & load resource data
  261. // DataStreamPtr dstream =
  262. // ResourceGroupManager::getSingleton().openResource(
  263. // mName, mGroup, true, this);
  264. // loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
  265. // }
  266. // else
  267. // {
  268. // // Load from 6 separate files
  269. // // Use OGRE its own codecs
  270. // String baseName, ext;
  271. // size_t pos = mName.find_last_of(".");
  272. // baseName = mName.substr(0, pos);
  273. // if ( pos != String::npos )
  274. // ext = mName.substr(pos+1);
  275. // static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"};
  276. // for(size_t i = 0; i < 6; i++)
  277. // {
  278. // String fullName = baseName + suffixes[i];
  279. // if (!ext.empty())
  280. // fullName = fullName + "." + ext;
  281. // // find & load resource data intro stream to allow resource
  282. // // group changes if required
  283. // DataStreamPtr dstream =
  284. // ResourceGroupManager::getSingleton().openResource(
  285. // fullName, mGroup, true, this);
  286. // loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
  287. // }
  288. // }
  289. // return loadedStreams;
  290. //}
  291. /****************************************************************************************/
  292. // TODO PORT - Loading tex from streams not supported
  293. //D3D9Texture::LoadedStreams D3D9Texture::_prepareVolumeTex()
  294. //{
  295. // assert(getTextureType() == TEX_TYPE_3D);
  296. // // find & load resource data
  297. // DataStreamPtr dstream =
  298. // ResourceGroupManager::getSingleton().openResource(
  299. // mName, mGroup, true, this);
  300. // LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
  301. // loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
  302. // return loadedStreams;
  303. // }
  304. /****************************************************************************************/
  305. // TODO PORT - Loading tex from streams not supported
  306. //D3D9Texture::LoadedStreams D3D9Texture::_prepareNormTex()
  307. //{
  308. // assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D);
  309. // // find & load resource data
  310. // DataStreamPtr dstream =
  311. // ResourceGroupManager::getSingleton().openResource(
  312. // mName, mGroup, true, this);
  313. // LoadedStreams loadedStreams = LoadedStreams(new vector<MemoryDataStreamPtr>::type());
  314. // loadedStreams->push_back(MemoryDataStreamPtr(new MemoryDataStream(dstream)));
  315. // return loadedStreams;
  316. //}
  317. /****************************************************************************************/
  318. void D3D9Texture::unprepareImpl()
  319. {
  320. if (mUsage & TU_RENDERTARGET)
  321. {
  322. return;
  323. }
  324. }
  325. /****************************************************************************************/
  326. void D3D9Texture::postLoadImpl(void)
  327. {
  328. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  329. // TODO PORT - Loading tex from streams not supported
  330. //mLoadedStreams.setNull();
  331. }
  332. /****************************************************************************************/
  333. void D3D9Texture::freeInternalResources(void)
  334. {
  335. freeInternalResourcesImpl();
  336. }
  337. /****************************************************************************************/
  338. void D3D9Texture::freeInternalResourcesImpl()
  339. {
  340. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  341. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin();
  342. while (it != mMapDeviceToTextureResources.end())
  343. {
  344. TextureResources* textureResource = it->second;
  345. freeTextureResources(it->first, textureResource);
  346. ++it;
  347. }
  348. }
  349. /****************************************************************************************/
  350. D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device)
  351. {
  352. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device);
  353. if (it == mMapDeviceToTextureResources.end())
  354. return NULL;
  355. return it->second;
  356. }
  357. /****************************************************************************************/
  358. D3D9Texture::TextureResources* D3D9Texture::allocateTextureResources(IDirect3DDevice9* d3d9Device)
  359. {
  360. assert(mMapDeviceToTextureResources.find(d3d9Device) == mMapDeviceToTextureResources.end());
  361. TextureResources* textureResources = new TextureResources;
  362. textureResources->pNormTex = NULL;
  363. textureResources->pCubeTex = NULL;
  364. textureResources->pVolumeTex = NULL;
  365. textureResources->pBaseTex = NULL;
  366. textureResources->pFSAASurface = NULL;
  367. mMapDeviceToTextureResources[d3d9Device] = textureResources;
  368. return textureResources;
  369. }
  370. /****************************************************************************************/
  371. void D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device)
  372. {
  373. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  374. prepareImpl();
  375. loadImpl(d3d9Device);
  376. postLoadImpl();
  377. }
  378. /****************************************************************************************/
  379. void D3D9Texture::freeTextureResources(IDirect3DDevice9* d3d9Device, D3D9Texture::TextureResources* textureResources)
  380. {
  381. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  382. // Release surfaces from each mip level.
  383. for(unsigned int i = 0; i < mSurfaceList.size(); ++i)
  384. {
  385. D3D9HardwarePixelBuffer* pixelBuffer = static_cast<D3D9HardwarePixelBuffer*>(mSurfaceList[i].get());
  386. pixelBuffer->releaseSurfaces(d3d9Device);
  387. }
  388. // Release the rest of the resources.
  389. SAFE_RELEASE(textureResources->pBaseTex);
  390. SAFE_RELEASE(textureResources->pNormTex);
  391. SAFE_RELEASE(textureResources->pCubeTex);
  392. SAFE_RELEASE(textureResources->pVolumeTex);
  393. SAFE_RELEASE(textureResources->pFSAASurface);
  394. }
  395. /****************************************************************************************/
  396. // TODO PORT - Loading tex from streams not supported
  397. // void D3D9Texture::_loadCubeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams)
  398. // {
  399. //assert(getTextureType() == TEX_TYPE_CUBE_MAP);
  400. // // DDS load?
  401. //if (getSourceFileType() == "dds")
  402. //{
  403. // // find & load resource data
  404. // assert(loadedStreams->size()==1);
  405. // DWORD usage = 0;
  406. // UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
  407. // D3DX_DEFAULT : mNumRequestedMipmaps + 1;
  408. //
  409. // D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  410. // const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  411. // // check if mip map volume textures are supported
  412. // if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
  413. // {
  414. // // no mip map support for this kind of textures :(
  415. // mNumMipmaps = 0;
  416. // numMips = 1;
  417. // }
  418. // // Determine D3D pool to use
  419. // D3DPOOL pool;
  420. // if (useDefaultPool())
  421. // {
  422. // pool = D3DPOOL_DEFAULT;
  423. // }
  424. // else
  425. // {
  426. // pool = D3DPOOL_MANAGED;
  427. // }
  428. //
  429. // TextureResources* textureResources;
  430. //
  431. // // Get or create new texture resources structure.
  432. // textureResources = getTextureResources(d3d9Device);
  433. // if (textureResources != NULL)
  434. // freeTextureResources(d3d9Device, textureResources);
  435. // else
  436. // textureResources = allocateTextureResources(d3d9Device);
  437. // HRESULT hr;
  438. // hr = D3DXCreateCubeTextureFromFileInMemoryEx(
  439. // d3d9Device,
  440. // (*loadedStreams)[0]->getPtr(),
  441. // static_cast<UINT>((*loadedStreams)[0]->size()),
  442. // D3DX_DEFAULT, // dims (square)
  443. // numMips,
  444. // usage,
  445. // D3DFMT_UNKNOWN,
  446. // pool,
  447. // D3DX_DEFAULT,
  448. // D3DX_DEFAULT,
  449. // 0, // colour key
  450. // NULL, // src box
  451. // NULL, // palette
  452. // &textureResources->pCubeTex);
  453. // if (FAILED(hr))
  454. // {
  455. // freeInternalResources();
  456. // OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't create cube texture: " + String(DXGetErrorDescription(hr)),
  457. // "D3D9Texture::_loadCubeTex" );
  458. // }
  459. // hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  460. // if (FAILED(hr))
  461. // {
  462. // freeInternalResources();
  463. // OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  464. // "D3D9Texture::_loadCubeTex" );
  465. // }
  466. // D3DSURFACE_DESC texDesc;
  467. // textureResources->pCubeTex->GetLevelDesc(0, &texDesc);
  468. // mD3DPool = texDesc.Pool;
  469. // // set src and dest attributes to the same, we can't know
  470. // _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
  471. // _setFinalAttributes(d3d9Device, textureResources,
  472. // texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
  473. // if( mHwGamma )
  474. // {
  475. // mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage,
  476. // D3DRTYPE_CUBETEXTURE,
  477. // texDesc.Format, false);
  478. // }
  479. // mInternalResourcesCreated = true;
  480. // }
  481. // else
  482. // {
  483. // assert(loadedStreams->size()==6);
  484. // String ext;
  485. // size_t pos = mName.find_last_of(".");
  486. // if ( pos != String::npos )
  487. // ext = mName.substr(pos+1);
  488. // vector<Image>::type images(6);
  489. // ConstImagePtrList imagePtrs;
  490. // for(size_t i = 0; i < 6; i++)
  491. // {
  492. // DataStreamPtr stream((*loadedStreams)[i]);
  493. // images[i].load(stream, ext);
  494. // imagePtrs.push_back(&images[i]);
  495. // }
  496. // _loadImages( imagePtrs );
  497. // }
  498. // }
  499. /****************************************************************************************/
  500. // TODO PORT - Loading tex from streams not supported
  501. // void D3D9Texture::_loadVolumeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams)
  502. // {
  503. // TODO PORT - Loading tex from streams not supported
  504. //assert(getTextureType() == TEX_TYPE_3D);
  505. //// DDS load?
  506. //if (getSourceFileType() == "dds")
  507. //{
  508. // // find & load resource data
  509. // assert(loadedStreams->size()==1);
  510. // DWORD usage = 0;
  511. // UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
  512. // D3DX_DEFAULT : mNumRequestedMipmaps + 1;
  513. //
  514. // D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  515. // const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  516. // // check if mip map volume textures are supported
  517. // if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
  518. // {
  519. // // no mip map support for this kind of textures :(
  520. // mNumMipmaps = 0;
  521. // numMips = 1;
  522. // }
  523. // // Determine D3D pool to use
  524. // D3DPOOL pool;
  525. // if (useDefaultPool())
  526. // {
  527. // pool = D3DPOOL_DEFAULT;
  528. // }
  529. // else
  530. // {
  531. // pool = D3DPOOL_MANAGED;
  532. // }
  533. //
  534. // TextureResources* textureResources;
  535. //
  536. // // Get or create new texture resources structure.
  537. // textureResources = getTextureResources(d3d9Device);
  538. // if (textureResources != NULL)
  539. // freeTextureResources(d3d9Device, textureResources);
  540. // else
  541. // textureResources = allocateTextureResources(d3d9Device);
  542. // HRESULT hr;
  543. // hr = D3DXCreateVolumeTextureFromFileInMemoryEx(
  544. // d3d9Device,
  545. // (*loadedStreams)[0]->getPtr(),
  546. // static_cast<UINT>((*loadedStreams)[0]->size()),
  547. // D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, // dims
  548. // numMips,
  549. // usage,
  550. // D3DFMT_UNKNOWN,
  551. // pool,
  552. // D3DX_DEFAULT,
  553. // D3DX_DEFAULT,
  554. // 0, // colour key
  555. // NULL, // src box
  556. // NULL, // palette
  557. // &textureResources->pVolumeTex);
  558. // if (FAILED(hr))
  559. // {
  560. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  561. // "Unable to load volume texture from: " + String(DXGetErrorDescription(hr)),
  562. // "D3D9Texture::_loadVolumeTex");
  563. // }
  564. // hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  565. // if (FAILED(hr))
  566. // {
  567. // freeInternalResources();
  568. // OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  569. // "D3D9Texture::_loadVolumeTex" );
  570. // }
  571. // D3DVOLUME_DESC texDesc;
  572. // hr = textureResources->pVolumeTex->GetLevelDesc(0, &texDesc);
  573. // mD3DPool = texDesc.Pool;
  574. // // set src and dest attributes to the same, we can't know
  575. // _setSrcAttributes(texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format));
  576. // _setFinalAttributes(d3d9Device, textureResources,
  577. // texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format));
  578. // if( mHwGamma )
  579. // {
  580. // mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage,
  581. // D3DRTYPE_VOLUMETEXTURE,
  582. // texDesc.Format, false);
  583. // }
  584. // mInternalResourcesCreated = true;
  585. // }
  586. //else
  587. //{
  588. // Image img;
  589. // assert(loadedStreams->size()==1);
  590. // size_t pos = mName.find_last_of(".");
  591. // String ext;
  592. // if ( pos != String::npos )
  593. // ext = mName.substr(pos+1);
  594. // DataStreamPtr stream((*loadedStreams)[0]);
  595. // img.load(stream, ext);
  596. // if (img.getHeight() == 0)
  597. // {
  598. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  599. // "Image height == 0 in " + getName(),
  600. // "D3D9Texture::_loadVolumeTex");
  601. // }
  602. // if (img.getWidth() == 0)
  603. // {
  604. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  605. // "Image width == 0 in " + getName(),
  606. // "D3D9Texture::_loadVolumeTex");
  607. // }
  608. // if (img.getDepth() == 0)
  609. // {
  610. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  611. // "Image depth == 0 in " + getName(),
  612. // "D3D9Texture::_loadVolumeTex");
  613. // }
  614. // // Call internal _loadImages, not loadImage since that's external and
  615. // // will determine load status etc again
  616. // ConstImagePtrList imagePtrs;
  617. // imagePtrs.push_back(&img);
  618. // _loadImages( imagePtrs );
  619. //}
  620. // }
  621. /****************************************************************************************/
  622. // TODO PORT - Loading tex from streams not supported
  623. // void D3D9Texture::_loadNormTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams)
  624. // {
  625. // TODO PORT - Loading tex from streams not supported
  626. //assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D);
  627. //// DDS load?
  628. //if (getSourceFileType() == "dds")
  629. //{
  630. // // Use D3DX
  631. // assert(loadedStreams->size()==1);
  632. // DWORD usage = 0;
  633. // UINT numMips;
  634. // if (mNumRequestedMipmaps == MIP_UNLIMITED)
  635. // numMips = D3DX_DEFAULT;
  636. // else if (mNumRequestedMipmaps == 0)
  637. // numMips = D3DX_FROM_FILE;
  638. // else
  639. // numMips = static_cast<UINT>(mNumRequestedMipmaps + 1);
  640. //
  641. // D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  642. // const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  643. // // check if mip map volume textures are supported
  644. // if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
  645. // {
  646. // // no mip map support for this kind of textures :(
  647. // mNumMipmaps = 0;
  648. // numMips = 1;
  649. // }
  650. // // Determine D3D pool to use
  651. // D3DPOOL pool;
  652. // if (useDefaultPool())
  653. // {
  654. // pool = D3DPOOL_DEFAULT;
  655. // }
  656. // else
  657. // {
  658. // pool = D3DPOOL_MANAGED;
  659. // }
  660. //
  661. // TextureResources* textureResources;
  662. //
  663. // // Get or create new texture resources structure.
  664. // textureResources = getTextureResources(d3d9Device);
  665. // if (textureResources != NULL)
  666. // freeTextureResources(d3d9Device, textureResources);
  667. // else
  668. // textureResources = allocateTextureResources(d3d9Device);
  669. // HRESULT hr;
  670. // hr = D3DXCreateTextureFromFileInMemoryEx(
  671. // d3d9Device,
  672. // (*loadedStreams)[0]->getPtr(),
  673. // static_cast<UINT>((*loadedStreams)[0]->size()),
  674. // D3DX_DEFAULT, D3DX_DEFAULT, // dims
  675. // numMips,
  676. // usage,
  677. // D3DFMT_UNKNOWN,
  678. // pool,
  679. // D3DX_DEFAULT,
  680. // D3DX_DEFAULT,
  681. // 0, // colour key
  682. // NULL, // src box
  683. // NULL, // palette
  684. // &textureResources->pNormTex);
  685. // if (FAILED(hr))
  686. // {
  687. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  688. // "Unable to load texture from :" + String(DXGetErrorDescription(hr)),
  689. // "D3D9Texture::_loadNormTex");
  690. // }
  691. // hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  692. // if (FAILED(hr))
  693. // {
  694. // freeInternalResources();
  695. // OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  696. // "D3D9Texture::_loadNormTex" );
  697. // }
  698. // D3DSURFACE_DESC texDesc;
  699. // textureResources->pNormTex->GetLevelDesc(0, &texDesc);
  700. // mD3DPool = texDesc.Pool;
  701. // // set src and dest attributes to the same, we can't know
  702. // _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
  703. // _setFinalAttributes(d3d9Device, textureResources,
  704. // texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
  705. // if( mHwGamma )
  706. // {
  707. // mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage,
  708. // D3DRTYPE_TEXTURE,
  709. // texDesc.Format, false);
  710. // }
  711. // mInternalResourcesCreated = true;
  712. // }
  713. //else
  714. //{
  715. // Image img;
  716. // // find & load resource data intro stream to allow resource
  717. // // group changes if required
  718. // assert(loadedStreams->size()==1);
  719. // size_t pos = mName.find_last_of(".");
  720. // String ext;
  721. // if ( pos != String::npos )
  722. // ext = mName.substr(pos+1);
  723. // DataStreamPtr stream((*loadedStreams)[0]);
  724. // img.load(stream, ext);
  725. // if (img.getHeight() == 0)
  726. // {
  727. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  728. // "Image height == 0 in " + getName(),
  729. // "D3D9Texture::_loadNormTex");
  730. // }
  731. // if (img.getWidth() == 0)
  732. // {
  733. // OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  734. // "Image width == 0 in " + getName(),
  735. // "D3D9Texture::_loadNormTex");
  736. // }
  737. // // Call internal _loadImages, not loadImage since that's external and
  738. // // will determine load status etc again
  739. // ConstImagePtrList imagePtrs;
  740. // imagePtrs.push_back(&img);
  741. // _loadImages( imagePtrs );
  742. //}
  743. // }
  744. /****************************************************************************************/
  745. size_t D3D9Texture::calculateSize(void) const
  746. {
  747. size_t instanceSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
  748. return instanceSize * mMapDeviceToTextureResources.size();
  749. }
  750. /****************************************************************************************/
  751. void D3D9Texture::createInternalResources(void)
  752. {
  753. createInternalResourcesImpl();
  754. }
  755. /****************************************************************************************/
  756. void D3D9Texture::determinePool()
  757. {
  758. if (useDefaultPool())
  759. {
  760. mD3DPool = D3DPOOL_DEFAULT;
  761. }
  762. else
  763. {
  764. mD3DPool = D3DPOOL_MANAGED;
  765. }
  766. }
  767. /****************************************************************************************/
  768. void D3D9Texture::createInternalResourcesImpl(void)
  769. {
  770. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  771. for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i)
  772. {
  773. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i);
  774. createInternalResourcesImpl(d3d9Device);
  775. }
  776. }
  777. /****************************************************************************************/
  778. void D3D9Texture::createInternalResourcesImpl(IDirect3DDevice9* d3d9Device)
  779. {
  780. TextureResources* textureResources;
  781. // Check if resources already exist.
  782. textureResources = getTextureResources(d3d9Device);
  783. if (textureResources != NULL && textureResources->pBaseTex != NULL)
  784. return;
  785. // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set
  786. // through setWidth and setHeight, which set mWidth and mHeight. Take those values.
  787. if(mSrcWidth == 0 || mSrcHeight == 0) {
  788. mSrcWidth = mWidth;
  789. mSrcHeight = mHeight;
  790. }
  791. // load based on tex.type
  792. switch (getTextureType())
  793. {
  794. case TEX_TYPE_1D:
  795. case TEX_TYPE_2D:
  796. _createNormTex(d3d9Device);
  797. break;
  798. case TEX_TYPE_CUBE_MAP:
  799. _createCubeTex(d3d9Device);
  800. break;
  801. case TEX_TYPE_3D:
  802. _createVolumeTex(d3d9Device);
  803. break;
  804. default:
  805. freeInternalResources();
  806. OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::createInternalResources" );
  807. }
  808. }
  809. /****************************************************************************************/
  810. void D3D9Texture::_createNormTex(IDirect3DDevice9* d3d9Device)
  811. {
  812. // we must have those defined here
  813. assert(mSrcWidth > 0 || mSrcHeight > 0);
  814. // determine wich D3D9 pixel format we'll use
  815. HRESULT hr;
  816. D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device);
  817. // let's D3DX check the corrected pixel format
  818. hr = D3DXCheckTextureRequirements(d3d9Device, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
  819. // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
  820. DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
  821. UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
  822. D3DX_DEFAULT : mNumRequestedMipmaps + 1;
  823. // Check dynamic textures
  824. if (mUsage & TU_DYNAMIC)
  825. {
  826. if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF))
  827. {
  828. usage |= D3DUSAGE_DYNAMIC;
  829. mDynamicTextures = true;
  830. }
  831. else
  832. {
  833. mDynamicTextures = false;
  834. }
  835. }
  836. // Check sRGB support
  837. if (mHwGamma)
  838. {
  839. mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, false);
  840. if (mUsage & TU_RENDERTARGET)
  841. mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, true);
  842. }
  843. // Check FSAA level
  844. if (mUsage & TU_RENDERTARGET)
  845. {
  846. D3D9RenderSystem* rsys = static_cast<D3D9RenderSystem*>(CamelotEngine::RenderSystemManager::getActive());
  847. rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false,
  848. &mFSAAType, &mFSAAQuality);
  849. }
  850. else
  851. {
  852. mFSAAType = D3DMULTISAMPLE_NONE;
  853. mFSAAQuality = 0;
  854. }
  855. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  856. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  857. // check if mip maps are supported on hardware
  858. mMipmapsHardwareGenerated = false;
  859. if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
  860. {
  861. if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
  862. {
  863. // use auto.gen. if available, and if desired
  864. mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF);
  865. if (mMipmapsHardwareGenerated)
  866. {
  867. usage |= D3DUSAGE_AUTOGENMIPMAP;
  868. numMips = 0;
  869. }
  870. }
  871. }
  872. else
  873. {
  874. // no mip map support for this kind of textures :(
  875. mNumMipmaps = 0;
  876. numMips = 1;
  877. }
  878. // derive the pool to use
  879. determinePool();
  880. TextureResources* textureResources;
  881. // Get or create new texture resources structure.
  882. textureResources = getTextureResources(d3d9Device);
  883. if (textureResources != NULL)
  884. freeTextureResources(d3d9Device, textureResources);
  885. else
  886. textureResources = allocateTextureResources(d3d9Device);
  887. // create the texture
  888. hr = D3DXCreateTexture(
  889. d3d9Device, // device
  890. static_cast<UINT>(mSrcWidth), // width
  891. static_cast<UINT>(mSrcHeight), // height
  892. numMips, // number of mip map levels
  893. usage, // usage
  894. d3dPF, // pixel format
  895. mD3DPool,
  896. &textureResources->pNormTex); // data pointer
  897. // check result and except if failed
  898. if (FAILED(hr))
  899. {
  900. freeInternalResources();
  901. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)),
  902. "D3D9Texture::_createNormTex" );
  903. }
  904. // set the base texture we'll use in the render system
  905. hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  906. if (FAILED(hr))
  907. {
  908. freeInternalResources();
  909. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  910. "D3D9Texture::_createNormTex" );
  911. }
  912. // set final tex. attributes from tex. description
  913. // they may differ from the source image !!!
  914. D3DSURFACE_DESC desc;
  915. hr = textureResources->pNormTex->GetLevelDesc(0, &desc);
  916. if (FAILED(hr))
  917. {
  918. freeInternalResources();
  919. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)),
  920. "D3D9Texture::_createNormTex" );
  921. }
  922. if (mFSAAType)
  923. {
  924. // create AA surface
  925. HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF,
  926. mFSAAType,
  927. mFSAAQuality,
  928. FALSE, // not lockable
  929. &textureResources->pFSAASurface, NULL);
  930. if (FAILED(hr))
  931. {
  932. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  933. "Unable to create AA render target: " + String(DXGetErrorDescription(hr)),
  934. "D3D9Texture::_createNormTex");
  935. }
  936. }
  937. _setFinalAttributes(d3d9Device, textureResources,
  938. desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));
  939. // Set best filter type
  940. if(mMipmapsHardwareGenerated)
  941. {
  942. hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device));
  943. if(FAILED(hr))
  944. {
  945. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)),
  946. "D3D9Texture::_createNormTex" );
  947. }
  948. }
  949. }
  950. /****************************************************************************************/
  951. void D3D9Texture::_createCubeTex(IDirect3DDevice9* d3d9Device)
  952. {
  953. // we must have those defined here
  954. assert(mSrcWidth > 0 || mSrcHeight > 0);
  955. // determine wich D3D9 pixel format we'll use
  956. HRESULT hr;
  957. D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device);
  958. // let's D3DX check the corrected pixel format
  959. hr = D3DXCheckCubeTextureRequirements(d3d9Device, NULL, NULL, 0, &d3dPF, mD3DPool);
  960. // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
  961. DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
  962. UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
  963. D3DX_DEFAULT : mNumRequestedMipmaps + 1;
  964. // Check dynamic textures
  965. if (mUsage & TU_DYNAMIC)
  966. {
  967. if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF))
  968. {
  969. usage |= D3DUSAGE_DYNAMIC;
  970. mDynamicTextures = true;
  971. }
  972. else
  973. {
  974. mDynamicTextures = false;
  975. }
  976. }
  977. // Check sRGB support
  978. if (mHwGamma)
  979. {
  980. mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, false);
  981. if (mUsage & TU_RENDERTARGET)
  982. mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, true);
  983. }
  984. // Check FSAA level
  985. if (mUsage & TU_RENDERTARGET)
  986. {
  987. D3D9RenderSystem* rsys = static_cast<D3D9RenderSystem*>(CamelotEngine::RenderSystemManager::getActive());
  988. rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false,
  989. &mFSAAType, &mFSAAQuality);
  990. }
  991. else
  992. {
  993. mFSAAType = D3DMULTISAMPLE_NONE;
  994. mFSAAQuality = 0;
  995. }
  996. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  997. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  998. // check if mip map cube textures are supported
  999. mMipmapsHardwareGenerated = false;
  1000. if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
  1001. {
  1002. if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
  1003. {
  1004. // use auto.gen. if available
  1005. mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF);
  1006. if (mMipmapsHardwareGenerated)
  1007. {
  1008. usage |= D3DUSAGE_AUTOGENMIPMAP;
  1009. numMips = 0;
  1010. }
  1011. }
  1012. }
  1013. else
  1014. {
  1015. // no mip map support for this kind of textures :(
  1016. mNumMipmaps = 0;
  1017. numMips = 1;
  1018. }
  1019. // derive the pool to use
  1020. determinePool();
  1021. TextureResources* textureResources;
  1022. // Get or create new texture resources structure.
  1023. textureResources = getTextureResources(d3d9Device);
  1024. if (textureResources != NULL)
  1025. freeTextureResources(d3d9Device, textureResources);
  1026. else
  1027. textureResources = allocateTextureResources(d3d9Device);
  1028. // create the texture
  1029. hr = D3DXCreateCubeTexture(
  1030. d3d9Device, // device
  1031. static_cast<UINT>(mSrcWidth), // dimension
  1032. numMips, // number of mip map levels
  1033. usage, // usage
  1034. d3dPF, // pixel format
  1035. mD3DPool,
  1036. &textureResources->pCubeTex); // data pointer
  1037. // check result and except if failed
  1038. if (FAILED(hr))
  1039. {
  1040. freeInternalResources();
  1041. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)),
  1042. "D3D9Texture::_createCubeTex" );
  1043. }
  1044. // set the base texture we'll use in the render system
  1045. hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  1046. if (FAILED(hr))
  1047. {
  1048. freeInternalResources();
  1049. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  1050. "D3D9Texture::_createCubeTex" );
  1051. }
  1052. // set final tex. attributes from tex. description
  1053. // they may differ from the source image !!!
  1054. D3DSURFACE_DESC desc;
  1055. hr = textureResources->pCubeTex->GetLevelDesc(0, &desc);
  1056. if (FAILED(hr))
  1057. {
  1058. freeInternalResources();
  1059. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)),
  1060. "D3D9Texture::_createCubeTex" );
  1061. }
  1062. if (mFSAAType)
  1063. {
  1064. // create AA surface
  1065. HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF,
  1066. mFSAAType,
  1067. mFSAAQuality,
  1068. FALSE, // not lockable
  1069. &textureResources->pFSAASurface, NULL);
  1070. if (FAILED(hr))
  1071. {
  1072. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
  1073. "Unable to create AA render target: " + String(DXGetErrorDescription(hr)),
  1074. "D3D9Texture::_createCubeTex");
  1075. }
  1076. }
  1077. _setFinalAttributes(d3d9Device, textureResources,
  1078. desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));
  1079. // Set best filter type
  1080. if(mMipmapsHardwareGenerated)
  1081. {
  1082. hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device));
  1083. if(FAILED(hr))
  1084. {
  1085. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)),
  1086. "D3D9Texture::_createCubeTex" );
  1087. }
  1088. }
  1089. }
  1090. /****************************************************************************************/
  1091. void D3D9Texture::_createVolumeTex(IDirect3DDevice9* d3d9Device)
  1092. {
  1093. // we must have those defined here
  1094. assert(mWidth > 0 && mHeight > 0 && mDepth>0);
  1095. if (mUsage & TU_RENDERTARGET)
  1096. {
  1097. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D9 Volume texture can not be created as render target !!",
  1098. "D3D9Texture::_createVolumeTex" );
  1099. }
  1100. // determine which D3D9 pixel format we'll use
  1101. HRESULT hr;
  1102. D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device);
  1103. // let's D3DX check the corrected pixel format
  1104. hr = D3DXCheckVolumeTextureRequirements(d3d9Device, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
  1105. // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
  1106. DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
  1107. UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
  1108. D3DX_DEFAULT : mNumRequestedMipmaps + 1;
  1109. // Check dynamic textures
  1110. if (mUsage & TU_DYNAMIC)
  1111. {
  1112. if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF))
  1113. {
  1114. usage |= D3DUSAGE_DYNAMIC;
  1115. mDynamicTextures = true;
  1116. }
  1117. else
  1118. {
  1119. mDynamicTextures = false;
  1120. }
  1121. }
  1122. // Check sRGB support
  1123. if (mHwGamma)
  1124. {
  1125. mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, false);
  1126. if (mUsage & TU_RENDERTARGET)
  1127. mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, true);
  1128. }
  1129. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1130. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  1131. // check if mip map volume textures are supported
  1132. mMipmapsHardwareGenerated = false;
  1133. if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)
  1134. {
  1135. if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
  1136. {
  1137. // use auto.gen. if available
  1138. mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF);
  1139. if (mMipmapsHardwareGenerated)
  1140. {
  1141. usage |= D3DUSAGE_AUTOGENMIPMAP;
  1142. numMips = 0;
  1143. }
  1144. }
  1145. }
  1146. else
  1147. {
  1148. // no mip map support for this kind of textures :(
  1149. mNumMipmaps = 0;
  1150. numMips = 1;
  1151. }
  1152. // derive the pool to use
  1153. determinePool();
  1154. TextureResources* textureResources;
  1155. // Get or create new texture resources structure.
  1156. textureResources = getTextureResources(d3d9Device);
  1157. if (textureResources != NULL)
  1158. freeTextureResources(d3d9Device, textureResources);
  1159. else
  1160. textureResources = allocateTextureResources(d3d9Device);
  1161. // create the texture
  1162. hr = D3DXCreateVolumeTexture(
  1163. d3d9Device, // device
  1164. static_cast<UINT>(mWidth), // dimension
  1165. static_cast<UINT>(mHeight),
  1166. static_cast<UINT>(mDepth),
  1167. numMips, // number of mip map levels
  1168. usage, // usage
  1169. d3dPF, // pixel format
  1170. mD3DPool,
  1171. &textureResources->pVolumeTex); // data pointer
  1172. // check result and except if failed
  1173. if (FAILED(hr))
  1174. {
  1175. freeInternalResources();
  1176. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)),
  1177. "D3D9Texture::_createVolumeTex" );
  1178. }
  1179. // set the base texture we'll use in the render system
  1180. hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex);
  1181. if (FAILED(hr))
  1182. {
  1183. freeInternalResources();
  1184. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)),
  1185. "D3D9Texture::_createVolumeTex" );
  1186. }
  1187. // set final tex. attributes from tex. description
  1188. // they may differ from the source image !!!
  1189. D3DVOLUME_DESC desc;
  1190. hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc);
  1191. if (FAILED(hr))
  1192. {
  1193. freeInternalResources();
  1194. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)),
  1195. "D3D9Texture::_createVolumeTex" );
  1196. }
  1197. _setFinalAttributes(d3d9Device, textureResources,
  1198. desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format));
  1199. // Set best filter type
  1200. if(mMipmapsHardwareGenerated)
  1201. {
  1202. hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device));
  1203. if(FAILED(hr))
  1204. {
  1205. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)),
  1206. "D3D9Texture::_createCubeTex" );
  1207. }
  1208. }
  1209. }
  1210. /****************************************************************************************/
  1211. void D3D9Texture::_setFinalAttributes(IDirect3DDevice9* d3d9Device,
  1212. TextureResources* textureResources,
  1213. unsigned long width, unsigned long height,
  1214. unsigned long depth, PixelFormat format)
  1215. {
  1216. // set target texture attributes
  1217. mHeight = height;
  1218. mWidth = width;
  1219. mDepth = depth;
  1220. mFormat = format;
  1221. // Create list of subsurfaces for getBuffer()
  1222. _createSurfaceList(d3d9Device, textureResources);
  1223. }
  1224. /****************************************************************************************/
  1225. void D3D9Texture::_setSrcAttributes(unsigned long width, unsigned long height,
  1226. unsigned long depth, PixelFormat format)
  1227. {
  1228. // set source image attributes
  1229. mSrcWidth = width;
  1230. mSrcHeight = height;
  1231. mSrcDepth = depth;
  1232. mSrcFormat = format;
  1233. }
  1234. /****************************************************************************************/
  1235. D3DTEXTUREFILTERTYPE D3D9Texture::_getBestFilterMethod(IDirect3DDevice9* d3d9Device)
  1236. {
  1237. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1238. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  1239. DWORD filterCaps = 0;
  1240. // Minification filter is used for mipmap generation
  1241. // Pick the best one supported for this tex type
  1242. switch (getTextureType())
  1243. {
  1244. case TEX_TYPE_1D: // Same as 2D
  1245. case TEX_TYPE_2D: filterCaps = rkCurCaps.TextureFilterCaps; break;
  1246. case TEX_TYPE_3D: filterCaps = rkCurCaps.VolumeTextureFilterCaps; break;
  1247. case TEX_TYPE_CUBE_MAP: filterCaps = rkCurCaps.CubeTextureFilterCaps; break;
  1248. }
  1249. if(filterCaps & D3DPTFILTERCAPS_MINFGAUSSIANQUAD)
  1250. return D3DTEXF_GAUSSIANQUAD;
  1251. if(filterCaps & D3DPTFILTERCAPS_MINFPYRAMIDALQUAD)
  1252. return D3DTEXF_PYRAMIDALQUAD;
  1253. if(filterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
  1254. return D3DTEXF_ANISOTROPIC;
  1255. if(filterCaps & D3DPTFILTERCAPS_MINFLINEAR)
  1256. return D3DTEXF_LINEAR;
  1257. if(filterCaps & D3DPTFILTERCAPS_MINFPOINT)
  1258. return D3DTEXF_POINT;
  1259. return D3DTEXF_POINT;
  1260. }
  1261. /****************************************************************************************/
  1262. bool D3D9Texture::_canUseDynamicTextures(IDirect3DDevice9* d3d9Device,
  1263. DWORD srcUsage,
  1264. D3DRESOURCETYPE srcType,
  1265. D3DFORMAT srcFormat)
  1266. {
  1267. HRESULT hr;
  1268. IDirect3D9* pD3D = NULL;
  1269. hr = d3d9Device->GetDirect3D(&pD3D);
  1270. if (FAILED(hr))
  1271. {
  1272. OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
  1273. "GetDirect3D failed !!!",
  1274. "D3D9Texture::_canUseDynamicTextures" );
  1275. }
  1276. if (pD3D != NULL)
  1277. pD3D->Release();
  1278. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1279. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  1280. D3DFORMAT eBackBufferFormat = device->getBackBufferFormat();
  1281. // Check for dynamic texture support
  1282. // check for auto gen. mip maps support
  1283. hr = pD3D->CheckDeviceFormat(
  1284. rkCurCaps.AdapterOrdinal,
  1285. rkCurCaps.DeviceType,
  1286. eBackBufferFormat,
  1287. srcUsage | D3DUSAGE_DYNAMIC,
  1288. srcType,
  1289. srcFormat);
  1290. if (hr == D3D_OK)
  1291. return true;
  1292. else
  1293. return false;
  1294. }
  1295. /****************************************************************************************/
  1296. bool D3D9Texture::_canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device,
  1297. DWORD srcUsage,
  1298. D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting)
  1299. {
  1300. HRESULT hr;
  1301. IDirect3D9* pD3D = NULL;
  1302. hr = d3d9Device->GetDirect3D(&pD3D);
  1303. if (FAILED(hr))
  1304. {
  1305. OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
  1306. "GetDirect3D failed !!!",
  1307. "D3D9Texture::_canUseDynamicTextures" );
  1308. }
  1309. if (pD3D != NULL)
  1310. pD3D->Release();
  1311. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1312. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  1313. D3DFORMAT eBackBufferFormat = device->getBackBufferFormat();
  1314. // Always check 'read' capability here
  1315. // We will check 'write' capability only in the context of a render target
  1316. if (forwriting)
  1317. srcUsage |= D3DUSAGE_QUERY_SRGBWRITE;
  1318. else
  1319. srcUsage |= D3DUSAGE_QUERY_SRGBREAD;
  1320. // Check for sRGB support
  1321. // check for auto gen. mip maps support
  1322. hr = pD3D->CheckDeviceFormat(
  1323. rkCurCaps.AdapterOrdinal,
  1324. rkCurCaps.DeviceType,
  1325. eBackBufferFormat,
  1326. srcUsage,
  1327. srcType,
  1328. srcFormat);
  1329. if (hr == D3D_OK)
  1330. return true;
  1331. else
  1332. return false;
  1333. }
  1334. /****************************************************************************************/
  1335. bool D3D9Texture::_canAutoGenMipmaps(IDirect3DDevice9* d3d9Device,
  1336. DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat)
  1337. {
  1338. HRESULT hr;
  1339. IDirect3D9* pD3D = NULL;
  1340. hr = d3d9Device->GetDirect3D(&pD3D);
  1341. if (FAILED(hr))
  1342. {
  1343. OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
  1344. "GetDirect3D failed !!!",
  1345. "D3D9Texture::_canUseDynamicTextures" );
  1346. }
  1347. if (pD3D != NULL)
  1348. pD3D->Release();
  1349. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1350. const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps();
  1351. D3DFORMAT eBackBufferFormat = device->getBackBufferFormat();
  1352. // Hacky override - many (all?) cards seem to not be able to autogen on
  1353. // textures which are not a power of two
  1354. // Can we even mipmap on 3D textures? Well
  1355. if ((mWidth & mWidth-1) || (mHeight & mHeight-1) || (mDepth & mDepth-1))
  1356. return false;
  1357. if (rkCurCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)
  1358. {
  1359. HRESULT hr;
  1360. // check for auto gen. mip maps support
  1361. hr = pD3D->CheckDeviceFormat(
  1362. rkCurCaps.AdapterOrdinal,
  1363. rkCurCaps.DeviceType,
  1364. eBackBufferFormat,
  1365. srcUsage | D3DUSAGE_AUTOGENMIPMAP,
  1366. srcType,
  1367. srcFormat);
  1368. // this HR could a SUCCES
  1369. // but mip maps will not be generated
  1370. if (hr == D3D_OK)
  1371. return true;
  1372. else
  1373. return false;
  1374. }
  1375. else
  1376. return false;
  1377. }
  1378. /****************************************************************************************/
  1379. D3DFORMAT D3D9Texture::_chooseD3DFormat(IDirect3DDevice9* d3d9Device)
  1380. {
  1381. // Choose frame buffer pixel format in case PF_UNKNOWN was requested
  1382. if(mFormat == PF_UNKNOWN)
  1383. {
  1384. D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device);
  1385. return device->getBackBufferFormat();
  1386. }
  1387. // Choose closest supported D3D format as a D3D format
  1388. return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mFormat));
  1389. }
  1390. /****************************************************************************************/
  1391. // Macro to hide ugly cast
  1392. #define GETLEVEL(face,mip) \
  1393. static_cast<D3D9HardwarePixelBuffer*>(mSurfaceList[face*(mNumMipmaps+1)+mip].get())
  1394. void D3D9Texture::_createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources)
  1395. {
  1396. IDirect3DSurface9 *surface;
  1397. IDirect3DVolume9 *volume;
  1398. D3D9HardwarePixelBuffer *buffer;
  1399. size_t mip, face;
  1400. assert(textureResources != NULL);
  1401. assert(textureResources->pBaseTex);
  1402. // Make sure number of mips is right
  1403. mNumMipmaps = textureResources->pBaseTex->GetLevelCount() - 1;
  1404. // Need to know static / dynamic
  1405. unsigned int bufusage;
  1406. if ((mUsage & TU_DYNAMIC) && mDynamicTextures)
  1407. {
  1408. bufusage = HardwareBuffer::HBU_DYNAMIC;
  1409. }
  1410. else
  1411. {
  1412. bufusage = HardwareBuffer::HBU_STATIC;
  1413. }
  1414. if (mUsage & TU_RENDERTARGET)
  1415. {
  1416. bufusage |= TU_RENDERTARGET;
  1417. }
  1418. uint surfaceCount = static_cast<uint>((getNumFaces() * (mNumMipmaps + 1)));
  1419. bool updateOldList = mSurfaceList.size() == surfaceCount;
  1420. if(!updateOldList)
  1421. {
  1422. // Create new list of surfaces
  1423. mSurfaceList.clear();
  1424. for(size_t face=0; face<getNumFaces(); ++face)
  1425. {
  1426. for(size_t mip=0; mip<=mNumMipmaps; ++mip)
  1427. {
  1428. buffer = new D3D9HardwarePixelBuffer((HardwareBuffer::Usage)bufusage, this);
  1429. mSurfaceList.push_back(HardwarePixelBufferPtr(buffer));
  1430. }
  1431. }
  1432. }
  1433. switch(getTextureType()) {
  1434. case TEX_TYPE_2D:
  1435. case TEX_TYPE_1D:
  1436. assert(textureResources->pNormTex);
  1437. // For all mipmaps, store surfaces as HardwarePixelBufferPtr
  1438. for(mip=0; mip<=mNumMipmaps; ++mip)
  1439. {
  1440. if(textureResources->pNormTex->GetSurfaceLevel(static_cast<UINT>(mip), &surface) != D3D_OK)
  1441. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed",
  1442. "D3D9Texture::_createSurfaceList");
  1443. D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip);
  1444. if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP))
  1445. currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated);
  1446. currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface,
  1447. mHwGammaWriteSupported, mFSAA, "PortNoName", textureResources->pBaseTex);
  1448. // decrement reference count, the GetSurfaceLevel call increments this
  1449. // this is safe because the pixel buffer keeps a reference as well
  1450. surface->Release();
  1451. }
  1452. break;
  1453. case TEX_TYPE_CUBE_MAP:
  1454. assert(textureResources->pCubeTex);
  1455. // For all faces and mipmaps, store surfaces as HardwarePixelBufferPtr
  1456. for(face=0; face<6; ++face)
  1457. {
  1458. for(mip=0; mip<=mNumMipmaps; ++mip)
  1459. {
  1460. if(textureResources->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, static_cast<UINT>(mip), &surface) != D3D_OK)
  1461. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get cubemap surface failed",
  1462. "D3D9Texture::getBuffer");
  1463. D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(face, mip);
  1464. if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP))
  1465. currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated);
  1466. currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface,
  1467. mHwGammaWriteSupported, mFSAA, "NoNamePort", textureResources->pBaseTex);
  1468. // decrement reference count, the GetSurfaceLevel call increments this
  1469. // this is safe because the pixel buffer keeps a reference as well
  1470. surface->Release();
  1471. }
  1472. }
  1473. break;
  1474. case TEX_TYPE_3D:
  1475. assert(textureResources->pVolumeTex);
  1476. // For all mipmaps, store surfaces as HardwarePixelBufferPtr
  1477. for(mip=0; mip<=mNumMipmaps; ++mip)
  1478. {
  1479. if(textureResources->pVolumeTex->GetVolumeLevel(static_cast<UINT>(mip), &volume) != D3D_OK)
  1480. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed",
  1481. "D3D9Texture::getBuffer");
  1482. D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip);
  1483. currPixelBuffer->bind(d3d9Device, volume, textureResources->pBaseTex);
  1484. if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP))
  1485. currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated);
  1486. // decrement reference count, the GetSurfaceLevel call increments this
  1487. // this is safe because the pixel buffer keeps a reference as well
  1488. volume->Release();
  1489. }
  1490. break;
  1491. };
  1492. }
  1493. #undef GETLEVEL
  1494. /****************************************************************************************/
  1495. HardwarePixelBufferPtr D3D9Texture::getBuffer(size_t face, size_t mipmap)
  1496. {
  1497. if(face >= getNumFaces())
  1498. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces",
  1499. "D3D9Texture::getBuffer");
  1500. if(mipmap > mNumMipmaps)
  1501. OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range",
  1502. "D3D9Texture::getBuffer");
  1503. size_t idx = face*(mNumMipmaps+1) + mipmap;
  1504. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
  1505. TextureResources* textureResources = getTextureResources(d3d9Device);
  1506. if (textureResources == NULL || textureResources->pBaseTex == NULL)
  1507. {
  1508. createTextureResources(d3d9Device);
  1509. textureResources = getTextureResources(d3d9Device);
  1510. }
  1511. assert(textureResources != NULL);
  1512. assert(idx < mSurfaceList.size());
  1513. return mSurfaceList[idx];
  1514. }
  1515. //---------------------------------------------------------------------
  1516. bool D3D9Texture::useDefaultPool()
  1517. {
  1518. // Determine D3D pool to use
  1519. // Use managed unless we're a render target or user has asked for
  1520. // a dynamic texture, and device supports D3DUSAGE_DYNAMIC (because default pool
  1521. // resources without the dynamic flag are not lockable)
  1522. return (mUsage & TU_RENDERTARGET) || ((mUsage & TU_DYNAMIC) && mDynamicTextures);
  1523. }
  1524. //---------------------------------------------------------------------
  1525. void D3D9Texture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device)
  1526. {
  1527. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  1528. if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES)
  1529. createTextureResources(d3d9Device);
  1530. }
  1531. //---------------------------------------------------------------------
  1532. void D3D9Texture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device)
  1533. {
  1534. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  1535. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device);
  1536. if (it != mMapDeviceToTextureResources.end())
  1537. {
  1538. TextureResources* textureResource = it->second;
  1539. // Destroy surfaces from each mip level.
  1540. for(unsigned int i = 0; i < mSurfaceList.size(); ++i)
  1541. {
  1542. D3D9HardwarePixelBuffer* pixelBuffer = static_cast<D3D9HardwarePixelBuffer*>(mSurfaceList[i].get());
  1543. pixelBuffer->destroyBufferResources(d3d9Device);
  1544. }
  1545. // Just free any internal resources, don't call unload() here
  1546. // because we want the un-touched resource to keep its unloaded status
  1547. // after device reset.
  1548. freeTextureResources(d3d9Device, textureResource);
  1549. SAFE_DELETE(textureResource);
  1550. mMapDeviceToTextureResources.erase(it);
  1551. }
  1552. }
  1553. //---------------------------------------------------------------------
  1554. void D3D9Texture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device)
  1555. {
  1556. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  1557. if(mD3DPool == D3DPOOL_DEFAULT)
  1558. {
  1559. DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device);
  1560. if (it != mMapDeviceToTextureResources.end())
  1561. {
  1562. TextureResources* textureResource = it->second;
  1563. // Just free any internal resources, don't call unload() here
  1564. // because we want the un-touched resource to keep its unloaded status
  1565. // after device reset.
  1566. freeTextureResources(d3d9Device, textureResource);
  1567. }
  1568. }
  1569. }
  1570. //---------------------------------------------------------------------
  1571. void D3D9Texture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device)
  1572. {
  1573. D3D9_DEVICE_ACCESS_CRITICAL_SECTION
  1574. if(mD3DPool == D3DPOOL_DEFAULT)
  1575. {
  1576. createTextureResources(d3d9Device);
  1577. }
  1578. }
  1579. //---------------------------------------------------------------------
  1580. IDirect3DBaseTexture9* D3D9Texture::getTexture()
  1581. {
  1582. TextureResources* textureResources;
  1583. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
  1584. textureResources = getTextureResources(d3d9Device);
  1585. if (textureResources == NULL || textureResources->pBaseTex == NULL)
  1586. {
  1587. createTextureResources(d3d9Device);
  1588. textureResources = getTextureResources(d3d9Device);
  1589. }
  1590. assert(textureResources);
  1591. assert(textureResources->pBaseTex);
  1592. return textureResources->pBaseTex;
  1593. }
  1594. //---------------------------------------------------------------------
  1595. IDirect3DTexture9* D3D9Texture::getNormTexture()
  1596. {
  1597. TextureResources* textureResources;
  1598. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
  1599. textureResources = getTextureResources(d3d9Device);
  1600. if (textureResources == NULL || textureResources->pNormTex == NULL)
  1601. {
  1602. createTextureResources(d3d9Device);
  1603. textureResources = getTextureResources(d3d9Device);
  1604. }
  1605. assert(textureResources);
  1606. assert(textureResources->pNormTex);
  1607. return textureResources->pNormTex;
  1608. }
  1609. //---------------------------------------------------------------------
  1610. IDirect3DCubeTexture9* D3D9Texture::getCubeTexture()
  1611. {
  1612. TextureResources* textureResources;
  1613. IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device();
  1614. textureResources = getTextureResources(d3d9Device);
  1615. if (textureResources == NULL || textureResources->pCubeTex)
  1616. {
  1617. createTextureResources(d3d9Device);
  1618. textureResources = getTextureResources(d3d9Device);
  1619. }
  1620. assert(textureResources);
  1621. assert(textureResources->pCubeTex);
  1622. return textureResources->pCubeTex;
  1623. }
  1624. /****************************************************************************************/
  1625. D3D9RenderTexture::D3D9RenderTexture(const String &name,
  1626. D3D9HardwarePixelBuffer *buffer,
  1627. bool writeGamma,
  1628. uint fsaa) : RenderTexture(buffer, 0)
  1629. {
  1630. mName = name;
  1631. mHwGamma = writeGamma;
  1632. mFSAA = fsaa;
  1633. }
  1634. //---------------------------------------------------------------------
  1635. void D3D9RenderTexture::update(bool swap)
  1636. {
  1637. D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager();
  1638. D3D9Device* currRenderWindowDevice = deviceManager->getActiveRenderTargetDevice();
  1639. if (currRenderWindowDevice != NULL)
  1640. {
  1641. if (currRenderWindowDevice->isDeviceLost() == false)
  1642. RenderTexture::update(swap);
  1643. }
  1644. else
  1645. {
  1646. for (UINT i=0; i < deviceManager->getDeviceCount(); ++i)
  1647. {
  1648. D3D9Device* device = deviceManager->getDevice(i);
  1649. if (device->isDeviceLost() == false)
  1650. {
  1651. deviceManager->setActiveRenderTargetDevice(device);
  1652. RenderTexture::update(swap);
  1653. deviceManager->setActiveRenderTargetDevice(NULL);
  1654. }
  1655. }
  1656. }
  1657. }
  1658. //---------------------------------------------------------------------
  1659. void D3D9RenderTexture::getCustomAttribute( const String& name, void *pData )
  1660. {
  1661. if(name == "DDBACKBUFFER")
  1662. {
  1663. if (mFSAA > 0)
  1664. {
  1665. // rendering to AA surface
  1666. IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
  1667. *pSurf = static_cast<D3D9HardwarePixelBuffer*>(mBuffer)->getFSAASurface(D3D9RenderSystem::getActiveD3D9Device());
  1668. return;
  1669. }
  1670. else
  1671. {
  1672. IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData;
  1673. *pSurf = static_cast<D3D9HardwarePixelBuffer*>(mBuffer)->getSurface(D3D9RenderSystem::getActiveD3D9Device());
  1674. return;
  1675. }
  1676. }
  1677. else if(name == "HWND")
  1678. {
  1679. HWND *pHwnd = (HWND*)pData;
  1680. *pHwnd = NULL;
  1681. return;
  1682. }
  1683. else if(name == "BUFFER")
  1684. {
  1685. *static_cast<HardwarePixelBuffer**>(pData) = mBuffer;
  1686. return;
  1687. }
  1688. }
  1689. //---------------------------------------------------------------------
  1690. void D3D9RenderTexture::swapBuffers(bool waitForVSync /* = true */)
  1691. {
  1692. // Only needed if we have to blit from AA surface
  1693. if (mFSAA > 0)
  1694. {
  1695. D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager();
  1696. D3D9HardwarePixelBuffer* buf = static_cast<D3D9HardwarePixelBuffer*>(mBuffer);
  1697. for (UINT i=0; i < deviceManager->getDeviceCount(); ++i)
  1698. {
  1699. D3D9Device* device = deviceManager->getDevice(i);
  1700. if (device->isDeviceLost() == false)
  1701. {
  1702. IDirect3DDevice9* d3d9Device = device->getD3D9Device();
  1703. HRESULT hr = d3d9Device->StretchRect(buf->getFSAASurface(d3d9Device), 0,
  1704. buf->getSurface(d3d9Device), 0, D3DTEXF_NONE);
  1705. if (FAILED(hr))
  1706. {
  1707. OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
  1708. "Unable to copy AA buffer to final buffer: " + String(DXGetErrorDescription(hr)),
  1709. "D3D9RenderTexture::swapBuffers");
  1710. }
  1711. }
  1712. }
  1713. }
  1714. }
  1715. }