Source code of Windows XP (NT5)
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.

996 lines
36 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 2000.
  3. //
  4. // psutil.cpp
  5. //
  6. // Direct3D Reference Device - Pixel Shader Utilities
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include "pch.cpp"
  10. #pragma hdrstop
  11. #define _ADDSTR( _Str ) {_snprintf( pStr, 256, "%s" _Str , pStr );}
  12. #define _ADDSTRP( _Str, _Param ) {_snprintf( pStr, 256, "%s" _Str , pStr, _Param );}
  13. //-----------------------------------------------------------------------------
  14. //
  15. // PixelShaderInstDisAsm - Generates instruction disassembly string for a single
  16. // pixel shader instruction. String interface is similar to _snprintf.
  17. //
  18. //-----------------------------------------------------------------------------
  19. int
  20. PixelShaderInstDisAsm(
  21. char* pStrRet, int StrSizeRet, DWORD* pShader, DWORD Flags )
  22. {
  23. UINT i,j;
  24. DWORD* pToken = pShader;
  25. // stage in local string, then copy
  26. char pStr[256] = "";
  27. DWORD Inst = *pToken++;
  28. if( Inst & D3DSI_COISSUE )
  29. {
  30. _ADDSTR("+");
  31. }
  32. DWORD Opcode = (Inst & D3DSI_OPCODE_MASK);
  33. DWORD DstParam = 0;
  34. DWORD SrcParam[3];
  35. DWORD SrcParamCount = 0;
  36. if (*pToken & (1L<<31))
  37. {
  38. DstParam = *pToken++;
  39. while (*pToken & (1L<<31))
  40. {
  41. SrcParam[SrcParamCount] = *pToken++;
  42. SrcParamCount++;
  43. }
  44. }
  45. switch (Opcode)
  46. {
  47. case D3DSIO_PHASE: _ADDSTR("phase"); break;
  48. case D3DSIO_NOP: _ADDSTR("nop"); break;
  49. case D3DSIO_MOV: _ADDSTR("mov"); break;
  50. case D3DSIO_ADD: _ADDSTR("add"); break;
  51. case D3DSIO_SUB: _ADDSTR("sub"); break;
  52. case D3DSIO_MUL: _ADDSTR("mul"); break;
  53. case D3DSIO_MAD: _ADDSTR("mad"); break;
  54. case D3DSIO_LRP: _ADDSTR("lrp"); break;
  55. case D3DSIO_CND: _ADDSTR("cnd"); break;
  56. case D3DSIO_DP3: _ADDSTR("dp3"); break;
  57. case D3DSIO_DEF: _ADDSTR("def"); break;
  58. case D3DSIO_DP4: _ADDSTR("dp4"); break;
  59. case D3DSIO_CMP: _ADDSTR("cmp"); break;
  60. case D3DSIO_FRC: _ADDSTR("frc"); break;
  61. case D3DSIO_BEM: _ADDSTR("bem"); break;
  62. case D3DSIO_TEXCOORD : if(SrcParamCount)
  63. _ADDSTR("texcrd")
  64. else
  65. _ADDSTR("texcoord");
  66. break;
  67. case D3DSIO_TEX : if(SrcParamCount)
  68. _ADDSTR("texld")
  69. else
  70. _ADDSTR("tex");
  71. break;
  72. case D3DSIO_TEXKILL : _ADDSTR("texkill"); break;
  73. case D3DSIO_TEXBEM_LEGACY:
  74. case D3DSIO_TEXBEM : _ADDSTR("texbem"); break;
  75. case D3DSIO_TEXBEML_LEGACY:
  76. case D3DSIO_TEXBEML : _ADDSTR("texbeml"); break;
  77. case D3DSIO_TEXREG2AR : _ADDSTR("texreg2ar"); break;
  78. case D3DSIO_TEXREG2GB : _ADDSTR("texreg2gb"); break;
  79. case D3DSIO_TEXM3x2PAD : _ADDSTR("texm3x2pad"); break;
  80. case D3DSIO_TEXM3x2TEX : _ADDSTR("texm3x2tex"); break;
  81. case D3DSIO_TEXM3x3PAD : _ADDSTR("texm3x3pad"); break;
  82. case D3DSIO_TEXM3x3TEX : _ADDSTR("texm3x3tex"); break;
  83. case D3DSIO_TEXM3x3SPEC : _ADDSTR("texm3x3spec"); break;
  84. case D3DSIO_TEXM3x3VSPEC: _ADDSTR("texm3x3vspec"); break;
  85. case D3DSIO_TEXM3x2DEPTH : _ADDSTR("texm3x2depth"); break;
  86. case D3DSIO_TEXDP3 : _ADDSTR("texdp3"); break;
  87. case D3DSIO_TEXREG2RGB : _ADDSTR("texreg2rgb"); break;
  88. case D3DSIO_TEXDEPTH : _ADDSTR("texdepth"); break;
  89. case D3DSIO_TEXDP3TEX : _ADDSTR("texdp3tex"); break;
  90. case D3DSIO_TEXM3x3 : _ADDSTR("texm3x3"); break;
  91. case D3DSIO_END : _ADDSTR("END"); break;
  92. default:
  93. _ASSERT(FALSE,"Attempt to disassemble unknown instruction!");
  94. }
  95. if (DstParam)
  96. {
  97. switch ( (DstParam & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT )
  98. {
  99. default:
  100. case 0x0: break;
  101. case 0x1: _ADDSTR("_x2"); break;
  102. case 0x2: _ADDSTR("_x4"); break;
  103. case 0x3: _ADDSTR("_x8"); break;
  104. case 0xF: _ADDSTR("_d2"); break;
  105. case 0xE: _ADDSTR("_d4"); break;
  106. case 0xD: _ADDSTR("_d8"); break;
  107. }
  108. switch (DstParam & D3DSP_DSTMOD_MASK)
  109. {
  110. default:
  111. case D3DSPDM_NONE: break;
  112. case D3DSPDM_SATURATE: _ADDSTR("_sat"); break;
  113. }
  114. switch (DstParam & D3DSP_REGTYPE_MASK)
  115. {
  116. default:
  117. case D3DSPR_TEMP: _ADDSTRP(" r%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
  118. case D3DSPR_TEXTURE: _ADDSTRP(" t%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
  119. case D3DSPR_CONST: _ADDSTRP(" c%d", (DstParam & D3DSP_REGNUM_MASK) ); break;
  120. }
  121. if (D3DSP_WRITEMASK_ALL != (DstParam & D3DSP_WRITEMASK_ALL))
  122. {
  123. _ADDSTR(".");
  124. if (DstParam & D3DSP_WRITEMASK_0) _ADDSTR("r");
  125. if (DstParam & D3DSP_WRITEMASK_1) _ADDSTR("g");
  126. if (DstParam & D3DSP_WRITEMASK_2) _ADDSTR("b");
  127. if (DstParam & D3DSP_WRITEMASK_3) _ADDSTR("a");
  128. }
  129. if( D3DSIO_DEF == Opcode )
  130. {
  131. for( i = 0; i < 4; i++ )
  132. _ADDSTRP(", %f", (float)(*pToken++) );
  133. goto EXIT;
  134. }
  135. }
  136. for( i = 0; i < SrcParamCount; i++ )
  137. {
  138. _ADDSTR(",");
  139. switch (SrcParam[i] & D3DSP_SRCMOD_MASK)
  140. {
  141. default:
  142. case D3DSPSM_NONE: _ADDSTR(" "); break;
  143. case D3DSPSM_NEG: _ADDSTR(" -"); break;
  144. case D3DSPSM_BIAS: _ADDSTR(" "); break;
  145. case D3DSPSM_BIASNEG: _ADDSTR(" -"); break;
  146. case D3DSPSM_SIGN: _ADDSTR(" "); break;
  147. case D3DSPSM_SIGNNEG: _ADDSTR(" -"); break;
  148. case D3DSPSM_COMP: _ADDSTR(" 1-"); break;
  149. case D3DSPSM_X2: _ADDSTR(" "); break;
  150. case D3DSPSM_X2NEG: _ADDSTR(" -"); break;
  151. }
  152. switch (SrcParam[i] & D3DSP_REGTYPE_MASK)
  153. {
  154. case D3DSPR_TEMP: _ADDSTRP("r%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
  155. case D3DSPR_INPUT: _ADDSTRP("v%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
  156. case D3DSPR_CONST: _ADDSTRP("c%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
  157. case D3DSPR_TEXTURE: _ADDSTRP("t%d", (SrcParam[i] & D3DSP_REGNUM_MASK) ); break;
  158. }
  159. switch (SrcParam[i] & D3DSP_SRCMOD_MASK)
  160. {
  161. default:
  162. case D3DSPSM_NONE: break;
  163. case D3DSPSM_NEG: break;
  164. case D3DSPSM_BIAS: _ADDSTR("_bias"); break;
  165. case D3DSPSM_BIASNEG: _ADDSTR("_bias"); break;
  166. case D3DSPSM_SIGN: _ADDSTR("_bx2"); break;
  167. case D3DSPSM_SIGNNEG: _ADDSTR("_bx2"); break;
  168. case D3DSPSM_COMP: break;
  169. case D3DSPSM_X2: _ADDSTR("_x2"); break;
  170. case D3DSPSM_X2NEG: _ADDSTR("_x2"); break;
  171. case D3DSPSM_DZ: _ADDSTR("_db"); break;
  172. case D3DSPSM_DW: _ADDSTR("_da"); break;
  173. }
  174. switch (SrcParam[i] & D3DVS_SWIZZLE_MASK)
  175. {
  176. case D3DSP_NOSWIZZLE: break;
  177. case D3DSP_REPLICATEALPHA: _ADDSTR(".a"); break;
  178. case D3DSP_REPLICATERED: _ADDSTR(".r"); break;
  179. case D3DSP_REPLICATEGREEN: _ADDSTR(".g"); break;
  180. case D3DSP_REPLICATEBLUE: _ADDSTR(".b"); break;
  181. default:
  182. _ADDSTR(".");
  183. for(j = 0; j < 4; j++)
  184. {
  185. switch(((SrcParam[i] & D3DVS_SWIZZLE_MASK) >> (D3DVS_SWIZZLE_SHIFT + 2*j)) & 0x3)
  186. {
  187. case 0:
  188. _ADDSTR("r");
  189. break;
  190. case 1:
  191. _ADDSTR("g");
  192. break;
  193. case 2:
  194. _ADDSTR("b");
  195. break;
  196. case 3:
  197. _ADDSTR("a");
  198. break;
  199. }
  200. }
  201. break;
  202. }
  203. }
  204. EXIT:
  205. return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
  206. }
  207. int
  208. RDPSInstSrcDisAsm(
  209. char* pStrRet, int StrSizeRet, RDPSRegister& SrcReg, BYTE Swizzle, BOOL bNegate, BOOL bForceShowFullSwizzle = FALSE )
  210. {
  211. // stage in local string, then copy
  212. char pStr[256] = "";
  213. UINT i;
  214. BOOL bDoRegNum = TRUE;
  215. if( bNegate )
  216. _ADDSTR( "-" );
  217. switch( SrcReg.GetRegType() )
  218. {
  219. case RDPSREG_INPUT:
  220. _ADDSTR( "v" ); break;
  221. case RDPSREG_TEMP:
  222. _ADDSTR( "r" ); break;
  223. case RDPSREG_CONST:
  224. _ADDSTR( "c" ); break;
  225. case RDPSREG_TEXTURE:
  226. _ADDSTR( "t" ); break;
  227. case RDPSREG_POSTMODSRC:
  228. _ADDSTR( "postModSrc" ); break;
  229. case RDPSREG_SCRATCH:
  230. _ADDSTR( "scratch" ); break;
  231. case RDPSREG_QUEUEDWRITE:
  232. _ADDSTR( "queuedWrite" ); break;
  233. case RDPSREG_ZERO:
  234. _ADDSTR( "<0.0f>" ); bDoRegNum = FALSE; break;
  235. case RDPSREG_ONE:
  236. _ADDSTR( "<1.0f>" ); bDoRegNum = FALSE; break;
  237. case RDPSREG_TWO:
  238. _ADDSTR( "<2.0f>" ); bDoRegNum = FALSE; break;
  239. default:
  240. _ASSERT(FALSE,"RDPSInstSrcDisAsm - Unknown register type.");
  241. break;
  242. }
  243. if( bDoRegNum )
  244. {
  245. _ADDSTRP("%d", SrcReg.GetRegNum() );
  246. }
  247. if( !bForceShowFullSwizzle )
  248. {
  249. switch( Swizzle )
  250. {
  251. case RDPS_NOSWIZZLE: break;
  252. case RDPS_REPLICATERED: _ADDSTR( ".r" ); break;
  253. case RDPS_REPLICATEGREEN: _ADDSTR( ".g" ); break;
  254. case RDPS_REPLICATEBLUE: _ADDSTR( ".b" ); break;
  255. case RDPS_REPLICATEALPHA: _ADDSTR( ".a" ); break;
  256. default: bForceShowFullSwizzle = TRUE; break;
  257. }
  258. }
  259. if( bForceShowFullSwizzle )
  260. {
  261. _ADDSTR( "." );
  262. for( i=0; i<4; i++ )
  263. {
  264. switch( Swizzle & 0x3 )
  265. {
  266. case RDPS_SELECT_R: _ADDSTR("r"); break;
  267. case RDPS_SELECT_G: _ADDSTR("g"); break;
  268. case RDPS_SELECT_B: _ADDSTR("b"); break;
  269. case RDPS_SELECT_A: _ADDSTR("a"); break;
  270. }
  271. Swizzle >>= 2;
  272. }
  273. }
  274. return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
  275. }
  276. int
  277. RDPSInstDestDisAsm(
  278. char* pStrRet, int StrSizeRet, RDPSRegister& DestReg, BYTE WriteMask )
  279. {
  280. // stage in local string, then copy
  281. char pStr[256] = "";
  282. switch( DestReg.GetRegType() )
  283. {
  284. case RDPSREG_TEMP:
  285. _ADDSTR( "r" ); break;
  286. case RDPSREG_TEXTURE:
  287. _ADDSTR( "t" ); break;
  288. case RDPSREG_POSTMODSRC:
  289. _ADDSTR( "postModSrc" ); break;
  290. case RDPSREG_SCRATCH:
  291. _ADDSTR( "scratch" ); break;
  292. case RDPSREG_QUEUEDWRITE:
  293. _ADDSTR( "queuedWrite" ); break;
  294. default:
  295. _ASSERT(FALSE,"RDPSInstSrcDisAsm - Unknown or invalid destination register type.");
  296. break;
  297. }
  298. _ADDSTRP("%d", DestReg.GetRegNum() );
  299. if( 0 == WriteMask )
  300. {
  301. _ASSERT(FALSE,"RDPSInstSrcDisAsm - Invalid destination write mask (0).");
  302. }
  303. else if( RDPS_COMPONENTMASK_ALL != WriteMask )
  304. {
  305. _ADDSTR(".");
  306. if( RDPS_COMPONENTMASK_0 & WriteMask )
  307. {
  308. _ADDSTR("r");
  309. }
  310. if( RDPS_COMPONENTMASK_1 & WriteMask )
  311. {
  312. _ADDSTR("g");
  313. }
  314. if( RDPS_COMPONENTMASK_2 & WriteMask )
  315. {
  316. _ADDSTR("b");
  317. }
  318. if( RDPS_COMPONENTMASK_3 & WriteMask )
  319. {
  320. _ADDSTR("a");
  321. }
  322. }
  323. return _snprintf( pStrRet, StrSizeRet, "%s", pStr );
  324. }
  325. //-----------------------------------------------------------------------------
  326. //
  327. //
  328. //-----------------------------------------------------------------------------
  329. void
  330. RDPSDisAsm(BYTE* pRDPSInstBuffer, ConstDef* pConstDefs, UINT cConstDefs, FLOAT fMaxPixelShaderValue, DWORD dwVersion)
  331. {
  332. #define _InstParam(__INST) (*(__INST##_PARAMS UNALIGNED64*)pRDPSInstBuffer)
  333. #define _StepOverInst(__INST) pRDPSInstBuffer += sizeof(__INST##_PARAMS);
  334. #define _DeclArgs(__INST) __INST##_PARAMS& Args = _InstParam(__INST);
  335. // stage in local string, then copy
  336. char pStr[256] = "";
  337. char pTempStr[256] = "";
  338. _ADDSTR("-----------------------------------------------------------------------------");
  339. RDDebugPrintf( pStr ); *pStr = 0;
  340. _ADDSTR("CreatePixelShader - Listing refrast's 'RISC' translation of pixel shader. ");
  341. RDDebugPrintf( pStr ); *pStr = 0;
  342. _ADDSTR(" Using MaxPixelShaderValue: ");
  343. if( FLT_MAX == fMaxPixelShaderValue )
  344. {
  345. _ADDSTR("FLT_MAX");
  346. }
  347. else
  348. {
  349. _ADDSTRP("%f",fMaxPixelShaderValue);
  350. }
  351. RDDebugPrintf( pStr ); *pStr = 0;
  352. _ADDSTR(" Pixel shader version: ");
  353. _ADDSTRP("ps.%d", D3DSHADER_VERSION_MAJOR(dwVersion));
  354. _ADDSTRP(".%d", D3DSHADER_VERSION_MINOR(dwVersion));
  355. RDDebugPrintf( pStr ); *pStr = 0;
  356. _ADDSTR("-----------------------------------------------------------------------------");
  357. RDDebugPrintf( pStr ); *pStr = 0;
  358. for( UINT i = 0; i < cConstDefs; i++ )
  359. {
  360. _ADDSTRP("def c%d, [",pConstDefs[i].RegNum);
  361. _ADDSTRP("%f,",pConstDefs[i].f[0]);
  362. _ADDSTRP("%f,",pConstDefs[i].f[1]);
  363. _ADDSTRP("%f,",pConstDefs[i].f[2]);
  364. _ADDSTRP("%f] (post-MaxPSVal-clamp shown)",pConstDefs[i].f[3]);
  365. RDDebugPrintf( pStr ); *pStr = 0;
  366. }
  367. while(RDPSINST_END != _InstParam(RDPSINST_BASE).Inst)
  368. {
  369. #ifdef _IA64_
  370. _ASSERT(0 == ((ULONG_PTR)pRDPSInstBuffer & 0x7), "RDPSDisAsm() - Misaligned instuction pointer!");
  371. #endif
  372. switch(_InstParam(RDPSINST_BASE).Inst)
  373. {
  374. case RDPSINST_EVAL:
  375. {
  376. _DeclArgs(RDPSINST_EVAL)
  377. _ADDSTR("eval ");
  378. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL);
  379. _ADDSTRP("%s <-- ", pTempStr);
  380. _ADDSTRP("CoordSet: %d, ", Args.uiCoordSet );
  381. _ADDSTR("bIgnoreD3DTTFF_PROJECTED: ");
  382. if( Args.bIgnoreD3DTTFF_PROJECTED )
  383. {
  384. _ADDSTR( "TRUE");
  385. }
  386. else
  387. {
  388. _ADDSTR( "FALSE");
  389. }
  390. _ADDSTR(", bClamp: ");
  391. if( Args.bClamp )
  392. {
  393. _ADDSTR( "TRUE");
  394. }
  395. else
  396. {
  397. _ADDSTR( "FALSE");
  398. }
  399. }
  400. _StepOverInst(RDPSINST_EVAL)
  401. break;
  402. case RDPSINST_SAMPLE:
  403. {
  404. _DeclArgs(RDPSINST_SAMPLE)
  405. _ADDSTR("sample ");
  406. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s <-- ", pTempStr);
  407. _ADDSTRP("TexStage: %d, TexCoords: ", Args.uiStage);
  408. RDPSInstSrcDisAsm(pTempStr,256,Args.CoordReg,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
  409. }
  410. _StepOverInst(RDPSINST_SAMPLE)
  411. break;
  412. case RDPSINST_KILL:
  413. {
  414. _DeclArgs(RDPSINST_KILL)
  415. _ADDSTR("kill ");
  416. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s", pTempStr);
  417. }
  418. _StepOverInst(RDPSINST_KILL)
  419. break;
  420. case RDPSINST_BEM:
  421. {
  422. _DeclArgs(RDPSINST_BEM)
  423. _ADDSTR("bem ");
  424. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  425. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  426. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  427. _ADDSTRP("D3DTSS_BUMPENVMAT** Stage: %d", Args.uiStage);
  428. }
  429. _StepOverInst(RDPSINST_BEM)
  430. break;
  431. case RDPSINST_LUMINANCE:
  432. {
  433. _DeclArgs(RDPSINST_LUMINANCE)
  434. _ADDSTR("luminance ");
  435. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s <-- ", pTempStr);
  436. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  437. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  438. _ADDSTRP("D3DTSS_BUMPENVLSCALE/OFFSET Stage: %d", Args.uiStage);
  439. }
  440. _StepOverInst(RDPSINST_LUMINANCE)
  441. break;
  442. case RDPSINST_DEPTH:
  443. {
  444. _DeclArgs(RDPSINST_DEPTH)
  445. _ADDSTR("depth ");
  446. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,RDPS_COMPONENTMASK_ALL); _ADDSTRP("%s", pTempStr);
  447. }
  448. _StepOverInst(RDPSINST_DEPTH)
  449. break;
  450. case RDPSINST_SRCMOD:
  451. {
  452. _DeclArgs(RDPSINST_SRCMOD)
  453. _ADDSTR("srcMod ");
  454. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  455. if( Args.bComplement )
  456. _ADDSTR("1-");
  457. if( Args.bTimes2 )
  458. _ADDSTR("2*");
  459. if( Args.bTimes2 && Args.bBias )
  460. _ADDSTR("(");
  461. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
  462. if( Args.bBias )
  463. _ADDSTR("-0.5");
  464. if( Args.bTimes2 && Args.bBias )
  465. _ADDSTR(")");
  466. _ADDSTR(", Clamp[");
  467. if( -FLT_MAX == Args.fRangeMin )
  468. {
  469. _ADDSTR("-FLT_MAX,");
  470. }
  471. else
  472. {
  473. _ADDSTRP("%.0f,",Args.fRangeMin);
  474. }
  475. if( FLT_MAX == Args.fRangeMax )
  476. {
  477. _ADDSTR("FLT_MAX]");
  478. }
  479. else
  480. {
  481. _ADDSTRP("%.0f]",Args.fRangeMax);
  482. }
  483. }
  484. _StepOverInst(RDPSINST_SRCMOD)
  485. break;
  486. case RDPSINST_SWIZZLE:
  487. {
  488. _DeclArgs(RDPSINST_SWIZZLE)
  489. _ADDSTR("swizzle ");
  490. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  491. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,Args.Swizzle,FALSE,TRUE); _ADDSTRP("%s", pTempStr);
  492. }
  493. _StepOverInst(RDPSINST_SWIZZLE)
  494. break;
  495. case RDPSINST_DSTMOD:
  496. {
  497. _DeclArgs(RDPSINST_DSTMOD)
  498. _ADDSTR("dstMod ");
  499. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  500. RDPSInstSrcDisAsm(pTempStr,256,Args.DstReg,RDPS_NOSWIZZLE,FALSE); _ADDSTRP("%s", pTempStr);
  501. if( (1.0f == Args.fScale) ||
  502. (2.0f == Args.fScale) ||
  503. (4.0f == Args.fScale) ||
  504. (8.0f == Args.fScale) )
  505. {
  506. _ADDSTRP("*%.0f",Args.fScale);
  507. }
  508. else if( (0.5f == Args.fScale) ||
  509. (0.25f == Args.fScale) ||
  510. (0.125f == Args.fScale) )
  511. {
  512. _ADDSTRP("/%.0f",1/Args.fScale);
  513. }
  514. else
  515. _ASSERT(FALSE,"RDPSDisAsm - Unexpected dest shift.");
  516. _ADDSTR(", Clamp[");
  517. if( -FLT_MAX == Args.fRangeMin )
  518. {
  519. _ADDSTR("-FLT_MAX,");
  520. }
  521. else
  522. {
  523. if( Args.fRangeMin == ceil(Args.fRangeMin) )
  524. {
  525. _ADDSTRP("%.0f,",Args.fRangeMin);
  526. }
  527. else
  528. {
  529. _ADDSTRP("%.4f,",Args.fRangeMin);
  530. }
  531. }
  532. if( FLT_MAX == Args.fRangeMax )
  533. {
  534. _ADDSTR("FLT_MAX]");
  535. }
  536. else
  537. {
  538. if( Args.fRangeMax == floor(Args.fRangeMax) )
  539. {
  540. _ADDSTRP("%.0f]",Args.fRangeMax);
  541. }
  542. else
  543. {
  544. _ADDSTRP("%.4f]",Args.fRangeMax);
  545. }
  546. }
  547. }
  548. _StepOverInst(RDPSINST_DSTMOD)
  549. break;
  550. case RDPSINST_MOV:
  551. {
  552. _DeclArgs(RDPSINST_MOV)
  553. _ADDSTR("mov ");
  554. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  555. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
  556. }
  557. _StepOverInst(RDPSINST_MOV)
  558. break;
  559. case RDPSINST_RCP:
  560. {
  561. _DeclArgs(RDPSINST_RCP)
  562. _ADDSTR("rcp ");
  563. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  564. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
  565. }
  566. _StepOverInst(RDPSINST_RCP)
  567. break;
  568. case RDPSINST_FRC:
  569. {
  570. _DeclArgs(RDPSINST_FRC)
  571. _ADDSTR("frc ");
  572. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  573. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s", pTempStr);
  574. }
  575. _StepOverInst(RDPSINST_FRC)
  576. break;
  577. case RDPSINST_ADD:
  578. {
  579. _DeclArgs(RDPSINST_ADD)
  580. _ADDSTR("add ");
  581. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  582. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  583. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
  584. }
  585. _StepOverInst(RDPSINST_ADD)
  586. break;
  587. case RDPSINST_SUB:
  588. {
  589. _DeclArgs(RDPSINST_SUB)
  590. _ADDSTR("sub ");
  591. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  592. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  593. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
  594. }
  595. _StepOverInst(RDPSINST_SUB)
  596. break;
  597. case RDPSINST_MUL:
  598. {
  599. _DeclArgs(RDPSINST_MUL)
  600. _ADDSTR("mul ");
  601. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  602. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  603. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
  604. }
  605. _StepOverInst(RDPSINST_MUL)
  606. break;
  607. case RDPSINST_DP3:
  608. {
  609. _DeclArgs(RDPSINST_DP3)
  610. _ADDSTR("dp3 ");
  611. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  612. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  613. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
  614. }
  615. _StepOverInst(RDPSINST_DP3)
  616. break;
  617. case RDPSINST_DP4:
  618. {
  619. _DeclArgs(RDPSINST_DP4)
  620. _ADDSTR("dp4 ");
  621. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  622. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  623. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s", pTempStr);
  624. }
  625. _StepOverInst(RDPSINST_DP4)
  626. break;
  627. case RDPSINST_MAD:
  628. {
  629. _DeclArgs(RDPSINST_MAD)
  630. _ADDSTR("mad ");
  631. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  632. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  633. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  634. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
  635. }
  636. _StepOverInst(RDPSINST_MAD)
  637. break;
  638. case RDPSINST_LRP:
  639. {
  640. _DeclArgs(RDPSINST_LRP)
  641. _ADDSTR("lrp ");
  642. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  643. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  644. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  645. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
  646. }
  647. _StepOverInst(RDPSINST_LRP)
  648. break;
  649. case RDPSINST_CND:
  650. {
  651. _DeclArgs(RDPSINST_LRP)
  652. _ADDSTR("cnd ");
  653. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  654. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  655. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  656. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
  657. }
  658. _StepOverInst(RDPSINST_CND)
  659. break;
  660. case RDPSINST_CMP:
  661. {
  662. _DeclArgs(RDPSINST_CMP)
  663. _ADDSTR("cmp ");
  664. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s <-- ", pTempStr);
  665. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg0,RDPS_NOSWIZZLE,Args.bSrcReg0_Negate); _ADDSTRP("%s, ", pTempStr);
  666. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg1,RDPS_NOSWIZZLE,Args.bSrcReg1_Negate); _ADDSTRP("%s, ", pTempStr);
  667. RDPSInstSrcDisAsm(pTempStr,256,Args.SrcReg2,RDPS_NOSWIZZLE,Args.bSrcReg2_Negate); _ADDSTRP("%s", pTempStr);
  668. }
  669. _StepOverInst(RDPSINST_CMP)
  670. break;
  671. case RDPSINST_TEXCOVERAGE:
  672. // don't bother to spew this (ref specific)
  673. _StepOverInst(RDPSINST_TEXCOVERAGE)
  674. break;
  675. case RDPSINST_QUADLOOPBEGIN:
  676. // don't bother to spew this
  677. _StepOverInst(RDPSINST_QUADLOOPBEGIN)
  678. break;
  679. case RDPSINST_QUADLOOPEND:
  680. // don't bother to spew this
  681. _StepOverInst(RDPSINST_QUADLOOPEND)
  682. break;
  683. case RDPSINST_QUEUEWRITE:
  684. {
  685. _DeclArgs(RDPSINST_QUEUEWRITE)
  686. _ADDSTR("queueWrite ");
  687. RDPSInstDestDisAsm(pTempStr,256,Args.DstReg,Args.WriteMask); _ADDSTRP("%s", pTempStr);
  688. _StepOverInst(RDPSINST_QUEUEWRITE)
  689. break;
  690. }
  691. case RDPSINST_FLUSHQUEUE:
  692. _ADDSTR("flushQueue ");
  693. _StepOverInst(RDPSINST_FLUSHQUEUE)
  694. break;
  695. case RDPSINST_NEXTD3DPSINST:
  696. _ADDSTRP("------------------------------------------------- D3D PS Inst: '%s'",
  697. _InstParam(RDPSINST_NEXTD3DPSINST).pInst->Text);
  698. _StepOverInst(RDPSINST_NEXTD3DPSINST)
  699. break;
  700. default:
  701. _ASSERT(FALSE,"RDPSDisAsm - Unrecognized refrast internal pixel shader instruction.");
  702. break;
  703. }
  704. if( 0 != *pStr )
  705. {
  706. RDDebugPrintf( pStr );
  707. *pStr = 0;
  708. }
  709. }
  710. _ADDSTR("------------------------------------------------- End of pixel shader. ------");
  711. RDDebugPrintf( pStr );
  712. }
  713. //-----------------------------------------------------------------------------
  714. //
  715. // UpdateLegacyPixelShader - Constructs pixel shader which performs all of
  716. // the texture lookups, including bump mapping, for the legacy pixel shading
  717. // model. Result of running this shader is the full set of texture lookups
  718. // in the temporary registers, which are then blended with the pixel diffuse
  719. // and specular colors using the legacy texture blend code.
  720. //
  721. //-----------------------------------------------------------------------------
  722. // destination parameter token
  723. #define D3DSPD( _RegFile, _Num ) (\
  724. (1L<<31) | (D3DSPR_##_RegFile) |\
  725. ((_Num)&D3DSP_REGNUM_MASK) |\
  726. (D3DSP_WRITEMASK_0|D3DSP_WRITEMASK_1|D3DSP_WRITEMASK_2|D3DSP_WRITEMASK_3) )
  727. // source paramater token
  728. #define D3DPSPS( _RegFile, _Num ) (\
  729. (1L<<31) | ((_Num)&D3DSP_REGNUM_MASK) |\
  730. D3DSP_NOSWIZZLE | (D3DSPR_##_RegFile) )
  731. void
  732. RefRast::UpdateLegacyPixelShader( void )
  733. {
  734. if (m_pLegacyPixelShader) delete m_pLegacyPixelShader;
  735. m_pLegacyPixelShader = NULL;
  736. DWORD Tokens[64];
  737. DWORD* pToken = Tokens;
  738. *pToken++ = D3DPS_VERSION(0xfe,0xfe);
  739. BOOL bSkipNextStage = FALSE;
  740. for ( int iStage=0; iStage<D3DHAL_TSS_MAXSTAGES; iStage++ )
  741. {
  742. if ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_DISABLE )
  743. {
  744. break;
  745. }
  746. if (bSkipNextStage) { bSkipNextStage = FALSE; continue; }
  747. BOOL bIsBEM = ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_BUMPENVMAP );
  748. BOOL bIsBEML = ( m_pRD->m_TextureStageState[iStage].m_dwVal[D3DTSS_COLOROP] == D3DTOP_BUMPENVMAPLUMINANCE );
  749. if ( bIsBEM || bIsBEML )
  750. {
  751. // DX6/7 BEM(L) was set for stage with bump map (i.e. first of two), while DX8
  752. // BEM(L) is set for a subsequent stage, so we have to set a 'standard' texture
  753. // to this stage and BEM(L) for the next stage, then stop anything else from being
  754. // set for the next stage
  755. *pToken++ = D3DSIO_TEX;
  756. *pToken++ = D3DSPD(TEXTURE, iStage);
  757. *pToken++ = (bIsBEM) ? (D3DSIO_TEXBEM_LEGACY) : (D3DSIO_TEXBEML_LEGACY);
  758. *pToken++ = D3DSPD(TEXTURE, iStage+1);
  759. *pToken++ = D3DPSPS(TEXTURE, iStage);
  760. bSkipNextStage = TRUE;
  761. }
  762. else
  763. {
  764. // simple lookup into 'iStage' texture register
  765. *pToken++ = D3DSIO_TEX;
  766. *pToken++ = D3DSPD(TEXTURE, iStage);
  767. }
  768. }
  769. *pToken++ = D3DPS_END();
  770. if ( pToken > (Tokens+2) )
  771. {
  772. m_pLegacyPixelShader = new RDPShader;
  773. if (NULL == m_pLegacyPixelShader)
  774. DPFERR("E_OUTOFMEMORY");
  775. m_pLegacyPixelShader->Initialize( m_pRD, Tokens, 4*(pToken-Tokens), m_pRD->GetCaps8() );
  776. }
  777. if (m_pRD->m_pDbgMon) m_pRD->m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
  778. return;
  779. }
  780. //-----------------------------------------------------------------------------
  781. //
  782. // Pixel Shader DP2 Command Functions
  783. //
  784. //-----------------------------------------------------------------------------
  785. HRESULT
  786. RefDev::Dp2CreatePixelShader( DWORD handle, DWORD dwCodeSize, LPDWORD pCode )
  787. {
  788. HRESULT hr = S_OK;
  789. HR_RET( m_PShaderHandleArray.Grow( handle ) );
  790. //
  791. // Validation sequence
  792. //
  793. #if DBG
  794. _ASSERT( m_PShaderHandleArray[handle].m_tag == 0,
  795. "A shader exists with the given handle, tag is non-zero" );
  796. #endif
  797. _ASSERT( m_PShaderHandleArray[handle].m_pShader == NULL,
  798. "A shader exists with the given handle" );
  799. RDPShader* pShader;
  800. pShader = m_PShaderHandleArray[handle].m_pShader = new RDPShader;
  801. if( pShader == NULL )
  802. return E_OUTOFMEMORY;
  803. hr = pShader->Initialize( this, pCode, dwCodeSize, GetCaps8() );
  804. if( FAILED( hr ) )
  805. {
  806. delete pShader;
  807. m_PShaderHandleArray[handle].m_pShader = NULL;
  808. #if DBG
  809. m_PShaderHandleArray[handle].m_tag = 0;
  810. #endif
  811. return hr;
  812. }
  813. #if DBG
  814. // Everything successful, mark this handle as in use.
  815. m_PShaderHandleArray[handle].m_tag = 1;
  816. #endif
  817. if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
  818. return hr;
  819. }
  820. HRESULT
  821. RefDev::Dp2DeletePixelShader(LPD3DHAL_DP2COMMAND pCmd)
  822. {
  823. HRESULT hr = S_OK;
  824. LPD3DHAL_DP2PIXELSHADER pPS =
  825. (LPD3DHAL_DP2PIXELSHADER)(pCmd + 1);
  826. for( int i = 0; i < pCmd->wStateCount; i++ )
  827. {
  828. DWORD handle = pPS[i].dwHandle;
  829. _ASSERT( m_PShaderHandleArray.IsValidIndex( handle ),
  830. "DeletePixelShader: invalid shader handle" );
  831. _ASSERT( m_PShaderHandleArray[handle].m_pShader,
  832. "DeletePixelShader: invalid shader" );
  833. delete m_PShaderHandleArray[handle].m_pShader;
  834. m_PShaderHandleArray[handle].m_pShader = NULL;
  835. #if DBG
  836. m_PShaderHandleArray[handle].m_tag = 0;
  837. #endif
  838. if( handle == m_CurrentPShaderHandle )
  839. {
  840. m_CurrentPShaderHandle = 0;
  841. m_dwRastFlags |= RDRF_PIXELSHADER_CHANGED;
  842. }
  843. }
  844. if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSMODIFYSHADERS );
  845. return hr;
  846. }
  847. HRESULT
  848. RefDev::Dp2SetPixelShader(LPD3DHAL_DP2COMMAND pCmd)
  849. {
  850. HRESULT hr = S_OK;
  851. RDPShader* pShader = NULL;
  852. LPD3DHAL_DP2PIXELSHADER pPS =
  853. (LPD3DHAL_DP2PIXELSHADER)(pCmd + 1);
  854. // Just set the last Pixel Shader in this array
  855. DWORD handle = pPS[pCmd->wStateCount-1].dwHandle;
  856. if (handle)
  857. {
  858. if( !m_PShaderHandleArray.IsValidIndex( handle )
  859. ||
  860. (m_PShaderHandleArray[handle].m_pShader == NULL) )
  861. {
  862. DPFERR( "Such a Pixel Shader has not been created" );
  863. return E_INVALIDARG;
  864. }
  865. pShader = m_PShaderHandleArray[handle].m_pShader;
  866. }
  867. m_CurrentPShaderHandle = handle;
  868. m_dwRastFlags |= RDRF_PIXELSHADER_CHANGED;
  869. if( pShader )
  870. {
  871. for( UINT i = 0; i < pShader->m_cConstDefs; i++ )
  872. {
  873. // constant regs are duplicated for 4 pixel grid
  874. for (UINT iP=0; iP<4; iP++)
  875. {
  876. // Consts from DEF instructions have already been clamped,
  877. // so just copy them.
  878. memcpy( m_Rast.m_ConstReg[pShader->m_pConstDefs[i].RegNum][iP],
  879. pShader->m_pConstDefs[i].f, 4*sizeof(FLOAT) );
  880. }
  881. }
  882. }
  883. if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSSETSHADER );
  884. return hr;
  885. }
  886. HRESULT
  887. RefDev::Dp2SetPixelShaderConsts( DWORD StartReg, DWORD dwCount,
  888. LPDWORD pData )
  889. {
  890. HRESULT hr = S_OK;
  891. if ( (StartReg+dwCount) > RDPS_MAX_NUMCONSTREG )
  892. {
  893. DPFERR("start/count out of range in SetPixelShaderConstant");
  894. return D3DERR_INVALIDCALL;
  895. }
  896. FLOAT* pfData = (FLOAT*)pData;
  897. FLOAT fMin = -(GetCaps8()->MaxPixelShaderValue);
  898. FLOAT fMax = (GetCaps8()->MaxPixelShaderValue);
  899. UINT End = StartReg + dwCount;
  900. for (UINT iR=StartReg; iR<End; iR++)
  901. {
  902. // clamp constants on input to range of values in pixel shaders
  903. FLOAT fConst[4];
  904. fConst[0] = MAX( fMin, MIN( fMax, *(pfData+0) ) );
  905. fConst[1] = MAX( fMin, MIN( fMax, *(pfData+1) ) );
  906. fConst[2] = MAX( fMin, MIN( fMax, *(pfData+2) ) );
  907. fConst[3] = MAX( fMin, MIN( fMax, *(pfData+3) ) );
  908. pfData += 4;
  909. // constant regs are duplicated for 4 pixel grid
  910. for (UINT iP=0; iP<4; iP++)
  911. {
  912. m_Rast.m_ConstReg[iR][iP][0] = fConst[0];
  913. m_Rast.m_ConstReg[iR][iP][1] = fConst[1];
  914. m_Rast.m_ConstReg[iR][iP][2] = fConst[2];
  915. m_Rast.m_ConstReg[iR][iP][3] = fConst[3];
  916. }
  917. }
  918. if (m_pDbgMon) m_pDbgMon->StateChanged( D3DDM_SC_PSCONSTANTS );
  919. return hr;
  920. }
  921. ///////////////////////////////////////////////////////////////////////////////
  922. // end