Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
11 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // rtarget.hpp
  5. //
  6. // Direct3D Reference Device - Render Target Methods
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. //-----------------------------------------------------------------------------
  12. //
  13. // Constructor/Destructor
  14. //
  15. //-----------------------------------------------------------------------------
  16. RDRenderTarget::RDRenderTarget( void )
  17. {
  18. memset( this, 0, sizeof(*this) );
  19. }
  20. //-----------------------------------------------------------------------------
  21. RDRenderTarget::~RDRenderTarget( void )
  22. {
  23. if( m_bPreDX7DDI )
  24. {
  25. if( m_pColor ) delete m_pColor;
  26. if( m_pDepth ) delete m_pDepth;
  27. }
  28. return;
  29. }
  30. //-----------------------------------------------------------------------------
  31. //
  32. // ReadPixelColor - Reads color buffer bits and expands out into an RDColor
  33. // value. Buffer types without alpha return a 1.0 value for alpha. Low
  34. // bits of <8 bit colors are returned as zero.
  35. //
  36. //-----------------------------------------------------------------------------
  37. void
  38. RDRenderTarget::ReadPixelColor(
  39. INT32 iX, INT32 iY, UINT Sample,
  40. RDColor& Color)
  41. {
  42. if ( NULL == m_pColor->GetBits() ) return;
  43. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pColor );
  44. Color.ConvertFrom( m_pColor->GetSurfaceFormat(), pSurfaceBits );
  45. }
  46. //-----------------------------------------------------------------------------
  47. //
  48. // WritePixelColor - Takes an RDColor value, formats it for the color buffer
  49. // format, and writes the value into buffer.
  50. //
  51. // Dithering is applied here, when enabled, for <8 bits/channel surfaces.
  52. //
  53. //-----------------------------------------------------------------------------
  54. void
  55. RDRenderTarget::WritePixelColor(
  56. INT32 iX, INT32 iY, UINT Sample,
  57. const RDColor& Color, BOOL bDither)
  58. {
  59. if ( NULL == m_pColor->GetBits() ) return;
  60. // default to round to nearest
  61. FLOAT fRoundOffset = .5F;
  62. if ( bDither )
  63. {
  64. static FLOAT fDitherTable[16] =
  65. {
  66. .03125f, .53125f, .15625f, .65625f,
  67. .78125f, .28125f, .90625f, .40625f,
  68. .21875f, .71875f, .09375f, .59375f,
  69. .96875f, .46875f, .84375f, .34375f
  70. };
  71. // form 4 bit offset into dither table (2 LSB's of x and y) and get offset
  72. unsigned uDitherOffset = ( ( iX << 2) & 0xc ) | (iY & 0x3 );
  73. fRoundOffset = fDitherTable[uDitherOffset];
  74. }
  75. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pColor );
  76. Color.ConvertTo( m_pColor->GetSurfaceFormat(), fRoundOffset, pSurfaceBits );
  77. }
  78. void
  79. RDRenderTarget::WritePixelColor(
  80. INT32 iX, INT32 iY,
  81. const RDColor& Color, BOOL bDither)
  82. {
  83. for (int i=0; i<m_pColor->GetSamples(); i++)
  84. {
  85. WritePixelColor( iX, iY, i, Color, bDither );
  86. }
  87. }
  88. //-----------------------------------------------------------------------------
  89. //
  90. // Read/WritePixelDepth - Read/write depth buffer
  91. //
  92. //-----------------------------------------------------------------------------
  93. void
  94. RDRenderTarget::WritePixelDepth(
  95. INT32 iX, INT32 iY, UINT Sample,
  96. const RDDepth& Depth )
  97. {
  98. // don't write if no Z buffer
  99. if ( NULL == m_pDepth ) { return; }
  100. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pDepth );
  101. switch (m_pDepth->GetSurfaceFormat())
  102. {
  103. case RD_SF_Z16S0:
  104. *((UINT16*)pSurfaceBits) = UINT16(Depth);
  105. break;
  106. case RD_SF_Z24S8:
  107. case RD_SF_Z24X8:
  108. case RD_SF_Z24X4S4:
  109. {
  110. // need to do read-modify-write to not step on stencil
  111. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  112. uBufferBits &= ~(0xffffff00);
  113. uBufferBits |= (UINT32(Depth) << 8);
  114. *((UINT32*)pSurfaceBits) = uBufferBits;
  115. }
  116. break;
  117. case RD_SF_S8Z24:
  118. case RD_SF_X8Z24:
  119. case RD_SF_X4S4Z24:
  120. {
  121. // need to do read-modify-write to not step on stencil
  122. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  123. uBufferBits &= ~(0x00ffffff);
  124. uBufferBits |= (UINT32(Depth) & 0x00ffffff);
  125. *((UINT32*)pSurfaceBits) = uBufferBits;
  126. }
  127. break;
  128. case RD_SF_Z15S1:
  129. {
  130. // need to do read-modify-write to not step on stencil
  131. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  132. uBufferBits &= ~(0xfffe);
  133. uBufferBits |= (UINT16(Depth) << 1);
  134. *((UINT16*)pSurfaceBits) = uBufferBits;
  135. }
  136. break;
  137. case RD_SF_S1Z15:
  138. {
  139. // need to do read-modify-write to not step on stencil
  140. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  141. uBufferBits &= ~(0x7fff);
  142. uBufferBits |= (UINT16(Depth) & 0x7fff);
  143. *((UINT16*)pSurfaceBits) = uBufferBits;
  144. }
  145. break;
  146. case RD_SF_Z32S0:
  147. *((UINT32*)pSurfaceBits) = UINT32(Depth);
  148. break;
  149. }
  150. }
  151. void
  152. RDRenderTarget::WritePixelDepth(
  153. INT32 iX, INT32 iY,
  154. const RDDepth& Depth )
  155. {
  156. if ( NULL == m_pDepth ) { return; }
  157. for (int i=0; i<m_pDepth->GetSamples(); i++)
  158. {
  159. WritePixelDepth( iX, iY, i, Depth );
  160. }
  161. }
  162. //-----------------------------------------------------------------------------
  163. void
  164. RDRenderTarget::ReadPixelDepth(
  165. INT32 iX, INT32 iY, UINT Sample,
  166. RDDepth& Depth )
  167. {
  168. // don't read if no Z buffer
  169. if ( NULL == m_pDepth ) { return; }
  170. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pDepth );
  171. switch (m_pDepth->GetSurfaceFormat())
  172. {
  173. case RD_SF_Z16S0:
  174. Depth = *((UINT16*)pSurfaceBits);
  175. break;
  176. case RD_SF_Z24S8:
  177. case RD_SF_Z24X8:
  178. case RD_SF_Z24X4S4:
  179. // take upper 24 bits aligned to LSB
  180. Depth = ( *((UINT32*)pSurfaceBits) ) >> 8;
  181. break;
  182. case RD_SF_S8Z24:
  183. case RD_SF_X8Z24:
  184. case RD_SF_X4S4Z24:
  185. // take lower 24 bits
  186. Depth = ( *((UINT32*)pSurfaceBits) ) & 0x00ffffff;
  187. break;
  188. case RD_SF_Z15S1:
  189. // take upper 15 bits aligned to LSB
  190. Depth = (UINT16)(( *((UINT16*)pSurfaceBits) ) >> 1);
  191. break;
  192. case RD_SF_S1Z15:
  193. // take lower 15 bits
  194. Depth = (UINT16)(( *((UINT16*)pSurfaceBits) ) & 0x7fff);
  195. break;
  196. case RD_SF_Z32S0:
  197. Depth = *((UINT32*)pSurfaceBits);
  198. break;
  199. }
  200. }
  201. //-----------------------------------------------------------------------------
  202. //
  203. // Read/WritePixelStencil - Read/Write of stencil bits within depth buffer
  204. // surface; write is done with read-modify-write so depth bits are not disturbed;
  205. // stencil mask is applied outside
  206. //
  207. //-----------------------------------------------------------------------------
  208. void
  209. RDRenderTarget::WritePixelStencil(
  210. INT32 iX, INT32 iY, UINT Sample,
  211. UINT8 uStencil)
  212. {
  213. // don't write if no Z/Stencil buffer or no stencil in Z buffer
  214. if ( (NULL == m_pDepth ) ||
  215. ((RD_SF_Z24S8 != m_pDepth->GetSurfaceFormat()) &&
  216. (RD_SF_S8Z24 != m_pDepth->GetSurfaceFormat()) &&
  217. (RD_SF_S1Z15 != m_pDepth->GetSurfaceFormat()) &&
  218. (RD_SF_Z15S1 != m_pDepth->GetSurfaceFormat()) &&
  219. (RD_SF_Z24X4S4 != m_pDepth->GetSurfaceFormat()) &&
  220. (RD_SF_X4S4Z24 != m_pDepth->GetSurfaceFormat())) ) { return; }
  221. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pDepth );
  222. // need to do read-modify-write to not step on Z
  223. switch(m_pDepth->GetSurfaceFormat())
  224. {
  225. case RD_SF_Z24S8:
  226. {
  227. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  228. uBufferBits &= ~(0x000000ff);
  229. uBufferBits |= uStencil;
  230. *((UINT32*)pSurfaceBits) = uBufferBits;
  231. }
  232. break;
  233. case RD_SF_S8Z24:
  234. {
  235. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  236. uBufferBits &= ~(0xff000000);
  237. uBufferBits |= (uStencil << 24);
  238. *((UINT32*)pSurfaceBits) = uBufferBits;
  239. }
  240. break;
  241. case RD_SF_Z24X4S4:
  242. {
  243. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  244. uBufferBits &= ~(0x000000ff);
  245. uBufferBits |= (uStencil & 0xf);
  246. *((UINT32*)pSurfaceBits) = uBufferBits;
  247. }
  248. break;
  249. case RD_SF_X4S4Z24:
  250. {
  251. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  252. uBufferBits &= ~(0xff000000);
  253. uBufferBits |= ((uStencil & 0xf) << 24);
  254. *((UINT32*)pSurfaceBits) = uBufferBits;
  255. }
  256. break;
  257. case RD_SF_Z15S1:
  258. {
  259. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  260. uBufferBits &= ~(0x0001);
  261. uBufferBits |= uStencil & 0x1;
  262. *((UINT16*)pSurfaceBits) = uBufferBits;
  263. }
  264. break;
  265. case RD_SF_S1Z15:
  266. {
  267. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  268. uBufferBits &= ~(0x8000);
  269. uBufferBits |= uStencil << 15;
  270. *((UINT16*)pSurfaceBits) = uBufferBits;
  271. }
  272. break;
  273. }
  274. }
  275. void
  276. RDRenderTarget::WritePixelStencil(
  277. INT32 iX, INT32 iY,
  278. UINT8 uStencil)
  279. {
  280. if ( NULL == m_pDepth ) { return; }
  281. for (int i=0; i<m_pDepth->GetSamples(); i++)
  282. {
  283. WritePixelStencil( iX, iY, i, uStencil );
  284. }
  285. }
  286. //-----------------------------------------------------------------------------
  287. void
  288. RDRenderTarget::ReadPixelStencil(
  289. INT32 iX, INT32 iY, UINT Sample,
  290. UINT8& uStencil)
  291. {
  292. // don't read if no Z/Stencil buffer or no stencil in Z buffer
  293. if ( ( NULL == m_pDepth ) ||
  294. ((RD_SF_Z24S8 != m_pDepth->GetSurfaceFormat()) &&
  295. (RD_SF_S8Z24 != m_pDepth->GetSurfaceFormat()) &&
  296. (RD_SF_S1Z15 != m_pDepth->GetSurfaceFormat()) &&
  297. (RD_SF_Z15S1 != m_pDepth->GetSurfaceFormat()) &&
  298. (RD_SF_Z24X4S4 != m_pDepth->GetSurfaceFormat()) &&
  299. (RD_SF_X4S4Z24 != m_pDepth->GetSurfaceFormat()) ) ) { return; }
  300. char* pSurfaceBits = PixelAddress( iX, iY, 0, Sample, m_pDepth );
  301. switch(m_pDepth->GetSurfaceFormat())
  302. {
  303. case RD_SF_Z24S8:
  304. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) & 0xff );
  305. break;
  306. case RD_SF_S8Z24:
  307. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) >> 24 );
  308. break;
  309. case RD_SF_Z15S1:
  310. uStencil = (UINT8)( ( *((UINT16*)pSurfaceBits) ) & 0x1 );
  311. break;
  312. case RD_SF_S1Z15:
  313. uStencil = (UINT8)( ( *((UINT16*)pSurfaceBits) ) >> 15 );
  314. break;
  315. case RD_SF_Z24X4S4:
  316. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) & 0xf );
  317. break;
  318. case RD_SF_X4S4Z24:
  319. uStencil = (UINT8)( ( ( *((UINT32*)pSurfaceBits) ) >> 24 ) & 0xf);
  320. break;
  321. }
  322. }
  323. ///////////////////////////////////////////////////////////////////////////////
  324. // end