Counter Strike : Global Offensive Source Code
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.

708 lines
25 KiB

  1. //================ Copyright (c) Valve Corporation. All Rights Reserved. ===========================
  2. //
  3. // Per draw call gcm state
  4. //
  5. //==================================================================================================
  6. #define PPU_DRAW 0
  7. #ifndef SPU
  8. #define CELL_GCM_MEMCPY memcpy // PPU SNC has no such intrinsic
  9. #endif
  10. #ifndef SPU
  11. #include "sys/memory.h"
  12. #include "sysutil/sysutil_sysparam.h"
  13. #include "cell/sysmodule.h"
  14. #include "tier0/platform.h"
  15. #include "tier0/dbg.h"
  16. #include "tier1/utlbuffer.h"
  17. #include "cell/gcm.h"
  18. #include "gcmconfig.h"
  19. #include "ps3gcmmemory.h"
  20. #include "gcmstate.h"
  21. #include "gcmlabels.h"
  22. #include "gcmdrawstate.h"
  23. #include "ps3/ps3_helpers.h"
  24. #include <materialsystem/imaterialsystem.h>
  25. #include <vprof.h>
  26. #include "tier0/memdbgon.h"
  27. #else
  28. #include "spumgr_spu.h"
  29. #include "gcmdrawstate.h"
  30. #endif
  31. //--------------------------------------------------------------------------------------------------
  32. // Globals
  33. //--------------------------------------------------------------------------------------------------
  34. ALIGN128 CGcmDrawState gGcmDrawState[GCM_DRAWSTATE_MAX] ALIGN128_POST;
  35. CGcmDrawState* gpGcmDrawState = &gGcmDrawState[0];
  36. int g_bZcullAuto = 1;
  37. int g_nZcullDefault = 100;
  38. int g_nZcullMoveForward = 100;
  39. int g_nZcullPushBack = 100;
  40. SetVertexDataArrayCache_t g_cacheSetVertexDataArray[ D3D_MAX_STREAMS ];
  41. vec_float4 g_aFPConst[GCM_DS_MAXFPCONST] = {0,};
  42. vec_float4 g_aVPConst[GCM_DS_MAXVPCONST] = {0,};
  43. D3DStreamDesc g_dxGcmVertexStreamSources[D3D_MAX_STREAMS];
  44. uint32 g_UPHigh = 0;
  45. uint32 g_UPFrame;
  46. #ifndef SPU
  47. ALIGN16 uint8 g_aDynECB[GCM_DS_MAXDYNECB] ALIGN16_POST; // Ring buffer of dynamic cmds
  48. uint32 g_nDynECBIdx = 0;
  49. #endif
  50. #ifndef SPU
  51. ALIGN128 CGcmDrawState::FixedData gFixedData[GCM_DRAWSTATE_MAX] ALIGN128_POST;
  52. #else
  53. ALIGN128 CGcmDrawState::FixedData gFixedData[1] ALIGN128_POST;
  54. #endif
  55. #ifndef SPU
  56. ALIGN128 uint8 gPackData[GCM_DRAWSTATE_MAX][GCM_DS_MAXDATAPERDRAWCALL] ALIGN128_POST;
  57. #else
  58. ALIGN128 uint8 gPackData[1][GCM_DS_MAXDATAPERDRAWCALL] ALIGN128_POST;
  59. #endif
  60. //--------------------------------------------------------------------------------------------------
  61. // DX lookups etc..
  62. //--------------------------------------------------------------------------------------------------
  63. // THese tables are auto-generated in dxabstract.cpp, UnpackD3DRSITable()
  64. // They provide renderstate classes and their default values....
  65. uint8 g_d3drs_defvalue_indices[D3DRS_VALUE_LIMIT] =
  66. { 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0300 | 1, 0300 | 2, 0100 | 3, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0300 | 1, 0300 | 0, 0100 | 4, 0000 | 0, 0000 | 0, 0300 | 1, 0300 | 1, 0000 | 0, 0300 | 2, 0300 | 1, 0300 | 0, 0300 | 5, 0100 | 0, 0300 | 1, 0300 | 0, 0100 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0300 | 0, 0300 | 0, 0300 | 0, 0300 | 6, 0300 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0300 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0300 | 0, 0300 | 4, 0300 | 4, 0300 | 4, 0300 | 7, 0300 | 0, 0300 | 8, 0300 | 8, 0100 | 8, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0000 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0200 | 4, 0000 | 0, 0000 | 0, 0100 | 0, 0300 | 0, 0100 | 4, 0100 | 4, 0100 | 0, 0000 | 0, 0100 | 0, 0100 | 3, 0100 | 0, 0100 | 0, 0000 | 0, 0000 | 0, 0100 | 0, 0300 | 0, 0000 | 0, 0100 | 6, 0100 | 6, 0100 | 0, 0100 | 0, 0100 | 6, 0100 | 0, 0100 | 0, 0300 | 4, 0300 | 8, 0100 | 0, 0000 | 0, 0100 | 0, 0100 | 9, 0100 | 0, 0300 | 4, 0000 | 0, 0100 | 0, 0300 | 4, 0100 | 2, 0100 | 4, 0300 | 0, 0300 | 0, 0100 | 0, 0000 | 0, 0100 | 6, 0100 | 6, 0100 | 0, 0100 | 0, 0100 | 6, 0100 | 0, 0100 | 0, 0300 | 0, 0300 | 4, 0300 | 4, 0300 | 4, 0300 | 7, 0300 | 10, 0300 | 10, 0300 | 10, 0100 | 8, 0300 | 0, 0300 | 0, 0000 | 0, 0000 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 0, 0100 | 3, 0100 | 4, 0100 | 4};
  67. uint32 g_d3drs_defvalues[11] =
  68. { 0x0, 0x31415926, 0x3, 0x2, 0x1, 0x7, 0x3F800000, 0x8, 0xFFFFFFFF, 0x42800000, 0xF };
  69. uint16 dxtogl_blendop[7] =
  70. {
  71. /*invalid*/CELL_GCM_FUNC_ADD,
  72. CELL_GCM_FUNC_ADD,
  73. CELL_GCM_FUNC_SUBTRACT,
  74. CELL_GCM_FUNC_REVERSE_SUBTRACT,
  75. CELL_GCM_MIN,
  76. CELL_GCM_MAX,
  77. /*invalid*/CELL_GCM_FUNC_ADD,
  78. };
  79. uint32 dxtogl_stencilmode[10] =
  80. {
  81. /*invalid*/ CELL_GCM_KEEP,
  82. /*D3DSTENCILOP_KEEP*/ CELL_GCM_KEEP,
  83. /*D3DSTENCILOP_ZERO*/ CELL_GCM_ZERO,
  84. /*D3DSTENCILOP_REPLACE*/ CELL_GCM_REPLACE,
  85. /*D3DSTENCILOP_INCRSAT*/ CELL_GCM_INCR,
  86. /*D3DSTENCILOP_DECRSAT*/ CELL_GCM_DECR,
  87. /*D3DSTENCILOP_INVERT*/ CELL_GCM_INVERT,
  88. /*D3DSTENCILOP_INCR*/ CELL_GCM_INCR_WRAP,
  89. /*D3DSTENCILOP_DECR*/ CELL_GCM_DECR_WRAP,
  90. /*invalid*/ CELL_GCM_KEEP,
  91. };
  92. // addressing modes
  93. // 1 D3DTADDRESS_WRAP Tile the texture at every integer junction.
  94. // D3DTADDRESS_MIRROR Similar to D3DTADDRESS_WRAP, except that the texture is flipped at every integer junction.
  95. // 3 D3DTADDRESS_CLAMP Texture coordinates outside the range [0.0, 1.0] are set to the texture color at 0.0 or 1.0, respectively.
  96. // 4 D3DTADDRESS_BORDER Texture coordinates outside the range [0.0, 1.0] are set to the border color.
  97. // D3DTADDRESS_MIRRORONCE Similar to D3DTADDRESS_MIRROR and D3DTADDRESS_CLAMP.
  98. // Takes the absolute value of the texture coordinate (thus, mirroring around 0),
  99. // and then clamps to the maximum value. The most common usage is for volume textures,
  100. // where support for the full D3DTADDRESS_MIRRORONCE texture-addressing mode is not
  101. // necessary, but the data is symmetric around the one axis.
  102. uint8 dxtogl_addressMode[6] =
  103. {
  104. CELL_GCM_TEXTURE_WRAP, // no zero entry
  105. CELL_GCM_TEXTURE_WRAP, // from D3DTADDRESS_WRAP
  106. CELL_GCM_TEXTURE_MIRROR, // from D3DTADDRESS_MIRROR
  107. CELL_GCM_TEXTURE_CLAMP_TO_EDGE, // from D3DTADDRESS_CLAMP
  108. CELL_GCM_TEXTURE_BORDER, // from D3DTADDRESS_BORDER
  109. CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER, // no D3DTADDRESS_MIRRORONCE support
  110. };
  111. uint8 dxtogl_anisoIndexHalf[32] = // indexed by [ dxsamp->maxAniso / 2 ]
  112. {
  113. CELL_GCM_TEXTURE_MAX_ANISO_1, // 0-1
  114. CELL_GCM_TEXTURE_MAX_ANISO_2, // 2-3
  115. CELL_GCM_TEXTURE_MAX_ANISO_4, // 4-5
  116. CELL_GCM_TEXTURE_MAX_ANISO_6, // 6-7
  117. CELL_GCM_TEXTURE_MAX_ANISO_8, // 8-9
  118. CELL_GCM_TEXTURE_MAX_ANISO_10, // 10-11
  119. CELL_GCM_TEXTURE_MAX_ANISO_12, // 12-13
  120. CELL_GCM_TEXTURE_MAX_ANISO_16, // 14-15
  121. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 16
  122. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 18
  123. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 20
  124. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 22
  125. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 24
  126. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 26
  127. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 28
  128. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 30
  129. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 32
  130. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 34
  131. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 36
  132. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 38
  133. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 40
  134. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 42
  135. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 44
  136. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 46
  137. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 48
  138. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 50
  139. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 52
  140. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 54
  141. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 56
  142. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 58
  143. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 60
  144. CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 62
  145. };
  146. uint8 dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
  147. {
  148. /* mip filter ---------------> D3DTEXF_NONE D3DTEXF_POINT D3DTEXF_LINEAR (D3DTEXF_ANISOTROPIC not applicable to mip filter) */
  149. /* min = D3DTEXF_NONE */ { CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_NEAREST_NEAREST, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_NEAREST }, // D3DTEXF_NONE we just treat like POINT
  150. /* min = D3DTEXF_POINT */ { CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_NEAREST_NEAREST, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_NEAREST },
  151. /* min = D3DTEXF_LINEAR */ { CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_LINEAR_NEAREST, CELL_GCM_TEXTURE_LINEAR_LINEAR, CELL_GCM_TEXTURE_NEAREST },
  152. /* min = D3DTEXF_ANISOTROPIC */ { CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_LINEAR_NEAREST, CELL_GCM_TEXTURE_LINEAR_LINEAR, CELL_GCM_TEXTURE_NEAREST }, // no diff from prior row, set maxAniso to effect the sampling
  153. };
  154. uint8 dxtogl_magFilter[4] = // indexed by _D3DTEXTUREFILTERTYPE
  155. {
  156. CELL_GCM_TEXTURE_NEAREST, // D3DTEXF_NONE not applicable to mag filter but we handle it like POINT (mat_showmiplevels hits this)
  157. CELL_GCM_TEXTURE_NEAREST, // D3DTEXF_POINT
  158. CELL_GCM_TEXTURE_LINEAR, // D3DTEXF_LINEAR
  159. CELL_GCM_TEXTURE_LINEAR, // D3DTEXF_ANISOTROPIC (aniso will be driven by setting maxAniso, not by a GL filter mode)
  160. };
  161. //--------------------------------------------------------------------------------------------------
  162. // Send to SPU
  163. //--------------------------------------------------------------------------------------------------
  164. #ifndef SPU
  165. int gSpuJobIssued = 0;
  166. uint32 gSpuStartIdx = 0;
  167. uint32 gSpuCount = 0;
  168. //--------------------------------------------------------------------------------------------------
  169. // SPU DRAW CODE
  170. //--------------------------------------------------------------------------------------------------
  171. #if !PPU_DRAW
  172. void CGcmDrawState::SendToSpu()
  173. {
  174. SpuTaskHandle *pTask = &g_ps3gcmGlobalState.m_spuHandle;
  175. // Get this drawcall indx and the next
  176. uint32 idx = gpGcmDrawState - gGcmDrawState;
  177. uint32 nextidx = (idx + 1) % GCM_DRAWSTATE_MAX;
  178. gSpuCount ++;
  179. // Move gpGcmDrawState to the next set of Data
  180. CGcmDrawState* pPrevDrawState = gpGcmDrawState;
  181. gpGcmDrawState = &gGcmDrawState[nextidx];
  182. gpGcmDrawState->m_shaderVxConstants = pPrevDrawState->m_shaderVxConstants;
  183. gpGcmDrawState->m_pPixelShaderData = pPrevDrawState->m_pPixelShaderData;
  184. gpGcmDrawState->m_pVertexShaderData = pPrevDrawState->m_pVertexShaderData;
  185. gpGcmDrawState->m_nBackBufferSize[0] = pPrevDrawState->m_nBackBufferSize[0];
  186. gpGcmDrawState->m_nBackBufferSize[1] = pPrevDrawState->m_nBackBufferSize[1];
  187. gpGcmDrawState->m_pDataCursor = gpGcmDrawState->m_pData;
  188. gpGcmDrawState->m_dirtySamplersMask = 0;
  189. gpGcmDrawState->m_dirtyCachesMask = 0;
  190. gpGcmDrawState->m_dirtyStatesMask = 0;
  191. gpGcmDrawState->m_nFreeLabel = 0;
  192. memset(gpGcmDrawState->m_pFixed->m_aSamplerIdx, 0xff, sizeof(m_pFixed->m_aSamplerIdx));
  193. gpGcmDrawState->m_pFixed->m_nSampler = 0;
  194. gpGcmDrawState->m_pFixed->m_nInstanced = 0;
  195. gpGcmDrawState->m_nNumECB = 0;
  196. memset(gpGcmDrawState->m_aECB, 0, sizeof(m_aECB));
  197. if ( (gSpuCount < 4) && (m_cmd != CmdEndFrame) ) return;
  198. // Send the state(s) to the SPU
  199. // Wait on previous drawcall
  200. if (gSpuJobIssued)
  201. {
  202. uint32 fifoPosn;
  203. gSpuMgr.ReadMailbox(pTask, &fifoPosn);
  204. gpGcmContext->current = (uint32*)fifoPosn;
  205. }
  206. // Makesure we have 16K at least, per drawcall (we issue 4 calls at a time)
  207. cellGcmReserveMethodSizeInline(gpGcmContext, (GCM_DS_FIFOPERDRAW*GCM_NUMDRAWCALLS_SPU)/4); // 16K per draw call, /4 because api takes wordcount
  208. // Makesure FIFO is on a 16B boundary
  209. while (uintp(gpGcmContext->current) & 0xf)
  210. {
  211. *gpGcmContext->current = 0;
  212. gpGcmContext->current++;
  213. }
  214. // Build count and startidx parameter to send to SPU
  215. uint32 mailboxparam = (gSpuCount<<16) | gSpuStartIdx;
  216. //Send this drawstate
  217. m_eaOutputFIFO = (uint32)gpGcmContext->current;
  218. __asm ( "eieio" );
  219. gSpuMgr.WriteMailbox(pTask, mailboxparam);
  220. gSpuJobIssued = 1;
  221. // If it's an endframe, wait for result now
  222. // comment out this if to always wait for the dma to come back
  223. if (m_cmd == CmdEndFrame)
  224. {
  225. uint32 fifoPosn;
  226. gSpuMgr.ReadMailbox(pTask, &fifoPosn);
  227. gpGcmContext->current = (uint32*)fifoPosn;
  228. gSpuJobIssued = 0;
  229. }
  230. gSpuStartIdx = nextidx;
  231. gSpuCount = 0;
  232. }
  233. #else // PPU_DRAW.....
  234. //--------------------------------------------------------------------------------------------------
  235. // Draw on PPU
  236. //--------------------------------------------------------------------------------------------------
  237. void CGcmDrawState::SendToSpu()
  238. {
  239. // Makesure we have 16K at least
  240. cellGcmReserveMethodSizeInline(gpGcmContext, GCM_DS_FIFOPERDRAW/4); // 16K per draw call
  241. // Makesure FIFO is on a 16B boundary
  242. while (uintp(gpGcmContext->current) & 0xf)
  243. {
  244. *gpGcmContext->current = 0;
  245. gpGcmContext->current++;
  246. }
  247. // Process cmd on PPU
  248. switch (m_cmd)
  249. {
  250. case CmdCommitStates:
  251. case CmdEndFrame:
  252. if (m_nFreeLabel) UnpackSetWriteBackEndLabel(GCM_LABEL_MEMORY_FREE, m_nFreeLabel);
  253. if ( m_dirtyStatesMask & kDirtyResetRsx) UnpackResetRsxState();
  254. if (m_dirtyStatesMask & kDirtyZeroAllPSConsts) ZeroFPConsts();
  255. if (m_dirtyStatesMask & kDirtyZeroAllVSConsts) ZeroVPConsts();
  256. UnpackData(); // Pulls out pixel shader consts and sets vertex shader consts
  257. CommitRenderStates();
  258. break;
  259. case CmdDrawPrim:
  260. {
  261. gpGcmDrawState->CommitAll((IDirect3DVertexDeclaration9 *)m_param[0], m_param[1]);
  262. // Draw
  263. GCM_FUNC( cellGcmSetDrawIndexArray,
  264. m_param[2], m_param[5],
  265. CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16, CELL_GCM_LOCATION_LOCAL,
  266. m_param[3] );
  267. }
  268. break;
  269. case CmdDrawPrimUP:
  270. {
  271. D3DStreamDesc &dsd = g_dxGcmVertexStreamSources[0];
  272. dsd.m_offset = 0;
  273. dsd.m_stride = m_param[2];
  274. dsd.m_vtxBuffer = ( IDirect3DVertexBuffer9 * )( uintp )1; // invalid pointer, but non-NULL to signal it's a real vertex buffer;
  275. dsd.m_nLocalBufferOffset = 0;
  276. gpGcmDrawState->CommitAll((IDirect3DVertexDeclaration9 *)m_param[0], 0);
  277. GCM_FUNC(cellGcmSetCallCommand, m_param[1]);
  278. }
  279. break;
  280. }
  281. // Flip to the other set of Data
  282. if (gpGcmDrawState->m_pData == gPackData1)
  283. {
  284. gpGcmDrawState->m_pData = gPackData2;
  285. gpGcmDrawState->m_pFixed = &gFixedData2;
  286. }
  287. else
  288. {
  289. gpGcmDrawState->m_pData = gPackData1;
  290. gpGcmDrawState->m_pFixed = &gFixedData1;
  291. }
  292. gpGcmDrawState->m_pDataCursor = gpGcmDrawState->m_pData;
  293. m_dirtySamplersMask = 0;
  294. m_dirtyCachesMask = 0;
  295. m_dirtyStatesMask = 0;
  296. m_nFreeLabel = 0;
  297. memset(m_pFixed->m_aSamplerIdx, 0xff, sizeof(m_pFixed->m_aSamplerIdx));
  298. m_pFixed->m_nSampler = 0;
  299. m_pFixed->m_nInstanced = 0;
  300. m_nNumECB = 0;
  301. memset(m_aECB, 0, sizeof(m_aECB));
  302. }
  303. #endif // ndef SPU
  304. #endif
  305. //--------------------------------------------------------------------------------------------------
  306. // test func to try to find corrupted ECBs
  307. //--------------------------------------------------------------------------------------------------
  308. void CGcmDrawState::TestCommandBuffer( uint8 *pCmdBuf )
  309. {
  310. uint8* pStart = pCmdBuf;
  311. uint8 *pReturnStack[20];
  312. uint8 **pSP = &pReturnStack[ARRAYSIZE(pReturnStack)];
  313. uint8 *pLastCmd;
  314. for(;;)
  315. {
  316. uint8 *pCmd=pCmdBuf;
  317. int nCmd = GetData<int>( pCmdBuf );
  318. if (nCmd > CBCMD_SET_VERTEX_SHADER_NEARZFARZ_STATE) DebuggerBreak();
  319. switch( nCmd )
  320. {
  321. case CBCMD_END:
  322. {
  323. if ( pSP == &pReturnStack[ARRAYSIZE(pReturnStack)] )
  324. return;
  325. else
  326. {
  327. // pop pc
  328. pCmdBuf = *( pSP ++ );
  329. break;
  330. }
  331. }
  332. case CBCMD_JUMP:
  333. pCmdBuf = GetData<uint8 *>( pCmdBuf + sizeof( int ) );
  334. break;
  335. case CBCMD_JSR:
  336. {
  337. Assert( pSP > &(pReturnStack[0] ) );
  338. // *(--pSP ) = pCmdBuf + sizeof( int ) + sizeof( uint8 *);
  339. // pCmdBuf = GetData<uint8 *>( pCmdBuf + sizeof( int ) );
  340. TestCommandBuffer( GetData<uint8 *>( pCmdBuf + sizeof( int ) ) );
  341. pCmdBuf = pCmdBuf + sizeof( int ) + sizeof( uint8 *);
  342. break;
  343. }
  344. case CBCMD_SET_PIXEL_SHADER_FLOAT_CONST:
  345. {
  346. int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
  347. int nNumConsts = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
  348. pCmdBuf += nNumConsts * 4 * sizeof( float ) + 3 * sizeof( int );
  349. break;
  350. }
  351. case CBCMD_SETPIXELSHADERFOGPARAMS:
  352. {
  353. Error("Pixel Shader Fog params not supported\n");
  354. break;
  355. }
  356. case CBCMD_STORE_EYE_POS_IN_PSCONST:
  357. {
  358. pCmdBuf += 2 * sizeof( int ) + sizeof( float );
  359. break;
  360. }
  361. case CBCMD_SET_DEPTH_FEATHERING_CONST:
  362. {
  363. // int nConst = GetData<int>( pCmdBuf + sizeof( int ) );
  364. // float fDepthBlendScale = GetData<float>( pCmdBuf + 2 * sizeof( int ) );
  365. pCmdBuf += 2 * sizeof( int ) + sizeof( float );
  366. // SetDepthFeatheringPixelShaderConstant( nConst, fDepthBlendScale );
  367. break;
  368. }
  369. case CBCMD_SET_VERTEX_SHADER_FLOAT_CONST:
  370. {
  371. int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
  372. int nNumConsts = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
  373. float const *pValues = reinterpret_cast< float const *> ( pCmdBuf + 3 * sizeof( int ) );
  374. pCmdBuf += nNumConsts * 4 * sizeof( float ) + 3 * sizeof( int );
  375. break;
  376. }
  377. case CBCMD_BIND_PS3_TEXTURE:
  378. {
  379. CPs3BindTexture_t tex = GetData<CPs3BindTexture_t> (pCmdBuf + sizeof( int ));
  380. if (tex.m_pLmBlock->Offset() & 0x7e) DebuggerBreak();
  381. pCmdBuf += sizeof(int) + sizeof(tex);
  382. break;
  383. }
  384. case CBCMD_BIND_PS3_STANDARD_TEXTURE:
  385. {
  386. CPs3BindTexture_t tex = GetData<CPs3BindTexture_t> (pCmdBuf + sizeof( int ));
  387. if (m_pFixed->m_nInstanced)
  388. {
  389. uint32 nBindFlags = tex.m_nBindFlags;
  390. uint32 nSampler = tex.m_sampler;
  391. switch (tex.m_boundStd)
  392. {
  393. case TEXTURE_LOCAL_ENV_CUBEMAP:
  394. if (m_pFixed->m_nInstanced & GCM_DS_INST_ENVMAP) tex = m_pFixed->m_instanceEnvCubemap;
  395. break;
  396. case TEXTURE_LIGHTMAP:
  397. if (m_pFixed->m_nInstanced & GCM_DS_INST_LIGHTMAP) tex = m_pFixed->m_instanceLightmap;
  398. break;
  399. case TEXTURE_PAINT:
  400. if (m_pFixed->m_nInstanced & GCM_DS_INST_PAINTMAP) tex = m_pFixed->m_instancePaintmap;
  401. break;
  402. }
  403. tex.m_nBindFlags = nBindFlags;
  404. tex.m_sampler = nSampler;
  405. }
  406. // Test texture
  407. if (tex.m_pLmBlock->Offset() & 0x7e) DebuggerBreak();
  408. pCmdBuf += sizeof(int) + sizeof(tex);
  409. break;
  410. }
  411. case CBCMD_PS3TEX:
  412. {
  413. pCmdBuf += sizeof(int) + (CBCMD_MAX_PS3TEX*sizeof(int));
  414. break;
  415. }
  416. case CBCMD_LENGTH:
  417. {
  418. pCmdBuf += sizeof(int) *2 ;
  419. break;
  420. }
  421. case CBCMD_SET_PSHINDEX:
  422. {
  423. // int nIdx = GetData<int>( pCmdBuf + sizeof( int ) );
  424. // ShaderManager()->SetPixelShaderIndex( nIdx );
  425. // pCmdBuf += 2 * sizeof( int );
  426. Error("PSHINDEX Not Supported\n");
  427. break;
  428. }
  429. case CBCMD_SET_VSHINDEX:
  430. {
  431. // int nIdx = GetData<int>( pCmdBuf + sizeof( int ) );
  432. // ShaderManager()->SetVertexShaderIndex( nIdx );
  433. pCmdBuf += 2 * sizeof( int );
  434. Error("VSHINDEX Not Supported\n");
  435. break;
  436. }
  437. case CBCMD_SET_VERTEX_SHADER_FLASHLIGHT_STATE:
  438. {
  439. // int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
  440. // SetVertexShaderConstantInternal( nStartConst, m_FlashlightWorldToTexture.Base(), 4, false );
  441. // pCmdBuf += 2 * sizeof( int );
  442. // Error("Flashlight unsupported\n");
  443. pCmdBuf += 2 * sizeof( int );
  444. break;
  445. }
  446. case CBCMD_SET_VERTEX_SHADER_NEARZFARZ_STATE:
  447. {
  448. Error("SetVertexShaderNearAndFarZ NOt SUPPORTED\n");
  449. // int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
  450. //
  451. // VMatrix m;
  452. //
  453. // m = m_MaterialProjectionMatrix;
  454. //
  455. // // GetMatrix( MATERIAL_PROJECTION, m.m[0] );
  456. //
  457. // // m[2][2] = F/(N-F) (flip sign if RH)
  458. // // m[3][2] = NF/(N-F)
  459. //
  460. // float vNearFar[4];
  461. //
  462. // float N = m[3][2] / m[2][2];
  463. // float F = (m[3][2]*N) / (N + m[3][2]);
  464. //
  465. // vNearFar[0] = N;
  466. // vNearFar[1] = F;
  467. //
  468. // SetVertexShaderConstantInternal( nStartConst, vNearFar, 1, false );
  469. pCmdBuf += 2 * sizeof( int );
  470. break;
  471. }
  472. case CBCMD_SET_PIXEL_SHADER_FLASHLIGHT_STATE:
  473. {
  474. // int nLightSampler = GetData<int>( pCmdBuf + sizeof( int ) );
  475. // int nDepthSampler = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
  476. // int nShadowNoiseSampler = GetData<int>( pCmdBuf + 3 * sizeof( int ) );
  477. // int nColorConst = GetData<int>( pCmdBuf + 4 * sizeof( int ) );
  478. // int nAttenConst = GetData<int>( pCmdBuf + 5 * sizeof( int ) );
  479. // int nOriginConst = GetData<int>( pCmdBuf + 6 * sizeof( int ) );
  480. // int nDepthTweakConst = GetData<int>( pCmdBuf + 7 * sizeof( int ) );
  481. // int nScreenScaleConst = GetData<int>( pCmdBuf + 8 * sizeof( int ) );
  482. // int nWorldToTextureConstant = GetData<int>( pCmdBuf + 9 * sizeof( int ) );
  483. // bool bFlashlightNoLambert = GetData<int>( pCmdBuf + 10 * sizeof( int ) ) != 0;
  484. // bool bSinglePassFlashlight = GetData<int>( pCmdBuf + 11 * sizeof( int ) ) != 0;
  485. // pCmdBuf += 12 * sizeof( int );
  486. //
  487. // ShaderAPITextureHandle_t hTexture = g_pShaderUtil->GetShaderAPITextureBindHandle( m_FlashlightState.m_pSpotlightTexture, m_FlashlightState.m_nSpotlightTextureFrame, 0 );
  488. // BindTexture( (Sampler_t)nLightSampler, TEXTURE_BINDFLAGS_SRGBREAD, hTexture ); // !!!BUG!!!srgb or not?
  489. //
  490. // SetPixelShaderConstantInternal( nAttenConst, m_pFlashlightAtten, 1, false );
  491. // SetPixelShaderConstantInternal( nOriginConst, m_pFlashlightPos, 1, false );
  492. //
  493. // m_pFlashlightColor[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term
  494. //
  495. // // DX10 hardware and single pass flashlight require a hack scalar since the flashlight is added in linear space
  496. // float flashlightColor[4] = { m_pFlashlightColor[0], m_pFlashlightColor[1], m_pFlashlightColor[2], m_pFlashlightColor[3] };
  497. // if ( ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) || ( bSinglePassFlashlight ) )
  498. // {
  499. // // Magic number that works well on the 360 and NVIDIA 8800
  500. // flashlightColor[0] *= 2.5f;
  501. // flashlightColor[1] *= 2.5f;
  502. // flashlightColor[2] *= 2.5f;
  503. // }
  504. //
  505. // SetPixelShaderConstantInternal( nColorConst, flashlightColor, 1, false );
  506. //
  507. // if ( nWorldToTextureConstant >= 0 )
  508. // {
  509. // SetPixelShaderConstantInternal( nWorldToTextureConstant, m_FlashlightWorldToTexture.Base(), 4, false );
  510. // }
  511. //
  512. // BindStandardTexture( (Sampler_t)nShadowNoiseSampler, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D );
  513. // if( m_pFlashlightDepthTexture && m_FlashlightState.m_bEnableShadows && ShaderUtil()->GetConfig().ShadowDepthTexture() )
  514. // {
  515. // ShaderAPITextureHandle_t hDepthTexture = g_pShaderUtil->GetShaderAPITextureBindHandle( m_pFlashlightDepthTexture, 0, 0 );
  516. // BindTexture( (Sampler_t)nDepthSampler, TEXTURE_BINDFLAGS_SHADOWDEPTH, hDepthTexture );
  517. //
  518. // SetPixelShaderConstantInternal( nDepthTweakConst, m_pFlashlightTweaks, 1, false );
  519. //
  520. // // Dimensions of screen, used for screen-space noise map sampling
  521. // float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
  522. // int nWidth, nHeight;
  523. // BaseClass::GetBackBufferDimensions( nWidth, nHeight );
  524. //
  525. // int nTexWidth, nTexHeight;
  526. // GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D );
  527. //
  528. // vScreenScale[0] = (float) nWidth / nTexWidth;
  529. // vScreenScale[1] = (float) nHeight / nTexHeight;
  530. // vScreenScale[2] = 1.0f / m_FlashlightState.m_flShadowMapResolution;
  531. // vScreenScale[3] = 2.0f / m_FlashlightState.m_flShadowMapResolution;
  532. // SetPixelShaderConstantInternal( nScreenScaleConst, vScreenScale, 1, false );
  533. // }
  534. // else
  535. // {
  536. // BindStandardTexture( (Sampler_t)nDepthSampler, TEXTURE_BINDFLAGS_NONE, TEXTURE_WHITE );
  537. // }
  538. // Error("Flashlight unsupported\n");
  539. pCmdBuf += 12 * sizeof( int );
  540. break;
  541. }
  542. case CBCMD_SET_PIXEL_SHADER_UBERLIGHT_STATE:
  543. {
  544. // int iEdge0Const = GetData<int>( pCmdBuf + sizeof( int ) );
  545. // int iEdge1Const = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
  546. // int iEdgeOOWConst = GetData<int>( pCmdBuf + 3 * sizeof( int ) );
  547. // int iShearRoundConst = GetData<int>( pCmdBuf + 4 * sizeof( int ) );
  548. // int iAABBConst = GetData<int>( pCmdBuf + 5 * sizeof( int ) );
  549. // int iWorldToLightConst = GetData<int>( pCmdBuf + 6 * sizeof( int ) );
  550. pCmdBuf += 7 * sizeof( int );
  551. //
  552. // SetPixelShaderConstantInternal( iEdge0Const, m_UberlightRenderState.m_vSmoothEdge0.Base(), 1, false );
  553. // SetPixelShaderConstantInternal( iEdge1Const, m_UberlightRenderState.m_vSmoothEdge1.Base(), 1, false );
  554. // SetPixelShaderConstantInternal( iEdgeOOWConst, m_UberlightRenderState.m_vSmoothOneOverW.Base(), 1, false );
  555. // SetPixelShaderConstantInternal( iShearRoundConst, m_UberlightRenderState.m_vShearRound.Base(), 1, false );
  556. // SetPixelShaderConstantInternal( iAABBConst, m_UberlightRenderState.m_vaAbB.Base(), 1, false );
  557. // SetPixelShaderConstantInternal( iWorldToLightConst, m_UberlightRenderState.m_WorldToLight.Base(), 4, false );
  558. Error("Uberlight state unsupported\n");
  559. break;
  560. }
  561. #ifndef NDEBUG
  562. default:
  563. Assert(0);
  564. break;
  565. #endif
  566. }
  567. pLastCmd = pCmd;
  568. }
  569. }