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.

329 lines
11 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // rtarget.hpp
  5. //
  6. // Direct3D Reference Rasterizer - Render Target Methods
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. //-----------------------------------------------------------------------------
  12. //
  13. // overload new & delete so that it can be allocated from caller-controlled
  14. // pool
  15. //
  16. //-----------------------------------------------------------------------------
  17. void*
  18. RRRenderTarget::operator new(size_t)
  19. {
  20. void* pMem = (void*)MEMALLOC( sizeof(RRRenderTarget) );
  21. _ASSERTa( NULL != pMem, "malloc failure on render target object", return NULL; );
  22. return pMem;
  23. }
  24. //-----------------------------------------------------------------------------
  25. void
  26. RRRenderTarget::operator delete(void* pv,size_t)
  27. {
  28. MEMFREE( pv );
  29. }
  30. //-----------------------------------------------------------------------------
  31. //
  32. // Constructor/Destructor
  33. //
  34. //-----------------------------------------------------------------------------
  35. RRRenderTarget::RRRenderTarget( void )
  36. {
  37. memset( this, 0, sizeof(*this) );
  38. }
  39. //-----------------------------------------------------------------------------
  40. RRRenderTarget::~RRRenderTarget( void )
  41. {
  42. // Release nothing because we didnt take any ref-counts,
  43. // simply return
  44. return;
  45. }
  46. //-----------------------------------------------------------------------------
  47. //
  48. // ReadPixelColor - Reads color buffer bits and expands out into an RRColor
  49. // value. Buffer types without alpha return a 1.0 value for alpha. Low
  50. // bits of <8 bit colors are returned as zero.
  51. //
  52. //-----------------------------------------------------------------------------
  53. void
  54. RRRenderTarget::ReadPixelColor(
  55. INT32 iX, INT32 iY,
  56. RRColor& Color)
  57. {
  58. if ( NULL == m_pColorBufBits ) return;
  59. char* pSurfaceBits =
  60. PixelAddress( iX, iY, m_pColorBufBits, m_iColorBufPitch, m_ColorSType );
  61. Color.ConvertFrom( m_ColorSType, pSurfaceBits );
  62. }
  63. //-----------------------------------------------------------------------------
  64. //
  65. // WritePixelColor - Takes an RRColor value, formats it for the color buffer
  66. // format, and writes the value into buffer.
  67. //
  68. // Dithering is applied here, when enabled, for <8 bits/channel surfaces.
  69. //
  70. //-----------------------------------------------------------------------------
  71. void
  72. RRRenderTarget::WritePixelColor(
  73. INT32 iX, INT32 iY,
  74. const RRColor& Color, BOOL bDither)
  75. {
  76. if ( NULL == m_pColorBufBits ) return;
  77. // default to round to nearest
  78. FLOAT fRoundOffset = .5F;
  79. if ( bDither )
  80. {
  81. static FLOAT fDitherTable[16] =
  82. {
  83. .0000f, .5000f, .1250f, .6750f,
  84. .7500f, .2500f, .8750f, .3750f,
  85. .1875f, .6875f, .0625f, .5625f,
  86. .9375f, .4375f, .8125f, .3125f
  87. };
  88. // form 4 bit offset into dither table (2 LSB's of x and y) and get offset
  89. unsigned uDitherOffset = ( ( iX << 2) & 0xc ) | (iY & 0x3 );
  90. fRoundOffset = fDitherTable[uDitherOffset];
  91. }
  92. char* pSurfaceBits = PixelAddress( iX, iY, m_pColorBufBits, m_iColorBufPitch, m_ColorSType );
  93. Color.ConvertTo( m_ColorSType, fRoundOffset, pSurfaceBits );
  94. }
  95. //-----------------------------------------------------------------------------
  96. //
  97. // Read/WritePixelDepth - Read/write depth buffer
  98. //
  99. //-----------------------------------------------------------------------------
  100. void
  101. RRRenderTarget::WritePixelDepth(
  102. INT32 iX, INT32 iY,
  103. const RRDepth& Depth )
  104. {
  105. // don't write if no Z buffer
  106. if ( NULL == m_pDepthBufBits ) { return; }
  107. char* pSurfaceBits =
  108. PixelAddress( iX, iY, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType );
  109. switch (m_DepthSType)
  110. {
  111. case RR_STYPE_Z16S0:
  112. *((UINT16*)pSurfaceBits) = UINT16(Depth);
  113. break;
  114. case RR_STYPE_Z24S8:
  115. case RR_STYPE_Z24S4:
  116. {
  117. // need to do read-modify-write to not step on stencil
  118. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  119. uBufferBits &= ~(0xffffff00);
  120. uBufferBits |= (UINT32(Depth) << 8);
  121. *((UINT32*)pSurfaceBits) = uBufferBits;
  122. }
  123. break;
  124. case RR_STYPE_S8Z24:
  125. case RR_STYPE_S4Z24:
  126. {
  127. // need to do read-modify-write to not step on stencil
  128. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  129. uBufferBits &= ~(0x00ffffff);
  130. uBufferBits |= (UINT32(Depth) & 0x00ffffff);
  131. *((UINT32*)pSurfaceBits) = uBufferBits;
  132. }
  133. break;
  134. case RR_STYPE_Z15S1:
  135. {
  136. // need to do read-modify-write to not step on stencil
  137. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  138. uBufferBits &= ~(0xfffe);
  139. uBufferBits |= (UINT16(Depth) << 1);
  140. *((UINT16*)pSurfaceBits) = uBufferBits;
  141. }
  142. break;
  143. case RR_STYPE_S1Z15:
  144. {
  145. // need to do read-modify-write to not step on stencil
  146. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  147. uBufferBits &= ~(0x7fff);
  148. uBufferBits |= (UINT16(Depth) & 0x7fff);
  149. *((UINT16*)pSurfaceBits) = uBufferBits;
  150. }
  151. break;
  152. case RR_STYPE_Z32S0:
  153. *((UINT32*)pSurfaceBits) = UINT32(Depth);
  154. break;
  155. }
  156. }
  157. //-----------------------------------------------------------------------------
  158. void
  159. RRRenderTarget::ReadPixelDepth(
  160. INT32 iX, INT32 iY,
  161. RRDepth& Depth )
  162. {
  163. // don't read if no Z buffer
  164. if ( NULL == m_pDepthBufBits ) { return; }
  165. char* pSurfaceBits =
  166. PixelAddress( iX, iY, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType );
  167. switch (m_DepthSType)
  168. {
  169. case RR_STYPE_Z16S0:
  170. Depth = *((UINT16*)pSurfaceBits);
  171. break;
  172. case RR_STYPE_Z24S8:
  173. case RR_STYPE_Z24S4:
  174. // take upper 24 bits aligned to LSB
  175. Depth = ( *((UINT32*)pSurfaceBits) ) >> 8;
  176. break;
  177. case RR_STYPE_S8Z24:
  178. case RR_STYPE_S4Z24:
  179. // take lower 24 bits
  180. Depth = ( *((UINT32*)pSurfaceBits) ) & 0x00ffffff;
  181. break;
  182. case RR_STYPE_Z15S1:
  183. // take upper 15 bits aligned to LSB
  184. Depth = (UINT16)(( *((UINT16*)pSurfaceBits) ) >> 1);
  185. break;
  186. case RR_STYPE_S1Z15:
  187. // take lower 15 bits
  188. Depth = (UINT16)(( *((UINT16*)pSurfaceBits) ) & 0x7fff);
  189. break;
  190. case RR_STYPE_Z32S0:
  191. Depth = *((UINT32*)pSurfaceBits);
  192. break;
  193. }
  194. }
  195. //-----------------------------------------------------------------------------
  196. //
  197. // Read/WritePixelStencil - Read/Write of stencil bits within depth buffer
  198. // surface; write is done with read-modify-write so depth bits are not disturbed;
  199. // stencil mask is applied outside
  200. //
  201. //-----------------------------------------------------------------------------
  202. void
  203. RRRenderTarget::WritePixelStencil(
  204. INT32 iX, INT32 iY,
  205. UINT8 uStencil)
  206. {
  207. // don't write if no Z/Stencil buffer or no stencil in Z buffer
  208. if ( (NULL == m_pDepthBufBits) ||
  209. ((RR_STYPE_Z24S8 != m_DepthSType) &&
  210. (RR_STYPE_S8Z24 != m_DepthSType) &&
  211. (RR_STYPE_S1Z15 != m_DepthSType) &&
  212. (RR_STYPE_Z15S1 != m_DepthSType) &&
  213. (RR_STYPE_Z24S4 != m_DepthSType) &&
  214. (RR_STYPE_S4Z24 != m_DepthSType)) ) { return; }
  215. char* pSurfaceBits =
  216. PixelAddress( iX, iY, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType );
  217. // need to do read-modify-write to not step on Z
  218. switch(m_DepthSType)
  219. {
  220. case RR_STYPE_Z24S8:
  221. {
  222. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  223. uBufferBits &= ~(0x000000ff);
  224. uBufferBits |= uStencil;
  225. *((UINT32*)pSurfaceBits) = uBufferBits;
  226. }
  227. break;
  228. case RR_STYPE_S8Z24:
  229. {
  230. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  231. uBufferBits &= ~(0xff000000);
  232. uBufferBits |= (uStencil << 24);
  233. *((UINT32*)pSurfaceBits) = uBufferBits;
  234. }
  235. break;
  236. case RR_STYPE_Z24S4:
  237. {
  238. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  239. uBufferBits &= ~(0x000000ff);
  240. uBufferBits |= (uStencil & 0xf);
  241. *((UINT32*)pSurfaceBits) = uBufferBits;
  242. }
  243. break;
  244. case RR_STYPE_S4Z24:
  245. {
  246. UINT32 uBufferBits = *((UINT32*)pSurfaceBits);
  247. uBufferBits &= ~(0xff000000);
  248. uBufferBits |= ((uStencil & 0xf) << 24);
  249. *((UINT32*)pSurfaceBits) = uBufferBits;
  250. }
  251. break;
  252. case RR_STYPE_Z15S1:
  253. {
  254. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  255. uBufferBits &= ~(0x0001);
  256. uBufferBits |= uStencil & 0x1;
  257. *((UINT16*)pSurfaceBits) = uBufferBits;
  258. }
  259. break;
  260. case RR_STYPE_S1Z15:
  261. {
  262. UINT16 uBufferBits = *((UINT16*)pSurfaceBits);
  263. uBufferBits &= ~(0x8000);
  264. uBufferBits |= uStencil << 15;
  265. *((UINT16*)pSurfaceBits) = uBufferBits;
  266. }
  267. break;
  268. }
  269. }
  270. //-----------------------------------------------------------------------------
  271. void
  272. RRRenderTarget::ReadPixelStencil(
  273. INT32 iX, INT32 iY,
  274. UINT8& uStencil)
  275. {
  276. // don't read if no Z/Stencil buffer or no stencil in Z buffer
  277. if ( (NULL == m_pDepthBufBits) ||
  278. ((RR_STYPE_Z24S8 != m_DepthSType) &&
  279. (RR_STYPE_S8Z24 != m_DepthSType) &&
  280. (RR_STYPE_S1Z15 != m_DepthSType) &&
  281. (RR_STYPE_Z15S1 != m_DepthSType) &&
  282. (RR_STYPE_Z24S4 != m_DepthSType) &&
  283. (RR_STYPE_S4Z24 != m_DepthSType) ) ) { return; }
  284. char* pSurfaceBits =
  285. PixelAddress( iX, iY, m_pDepthBufBits, m_iDepthBufPitch, m_DepthSType );
  286. switch(m_DepthSType)
  287. {
  288. case RR_STYPE_Z24S8:
  289. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) & 0xff );
  290. break;
  291. case RR_STYPE_S8Z24:
  292. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) >> 24 );
  293. break;
  294. case RR_STYPE_Z15S1:
  295. uStencil = (UINT8)( ( *((UINT16*)pSurfaceBits) ) & 0x1 );
  296. break;
  297. case RR_STYPE_S1Z15:
  298. uStencil = (UINT8)( ( *((UINT16*)pSurfaceBits) ) >> 15 );
  299. break;
  300. case RR_STYPE_Z24S4:
  301. uStencil = (UINT8)( ( *((UINT32*)pSurfaceBits) ) & 0xf );
  302. break;
  303. case RR_STYPE_S4Z24:
  304. uStencil = (UINT8)( ( ( *((UINT32*)pSurfaceBits) ) >> 24 ) & 0xf);
  305. break;
  306. }
  307. }
  308. ///////////////////////////////////////////////////////////////////////////////
  309. // end