//================ Copyright (c) Valve Corporation. All Rights Reserved. =========================== // // Per draw call gcm state // //================================================================================================== #define PPU_DRAW 0 #ifndef SPU #define CELL_GCM_MEMCPY memcpy // PPU SNC has no such intrinsic #endif #ifndef SPU #include "sys/memory.h" #include "sysutil/sysutil_sysparam.h" #include "cell/sysmodule.h" #include "tier0/platform.h" #include "tier0/dbg.h" #include "tier1/utlbuffer.h" #include "cell/gcm.h" #include "gcmconfig.h" #include "ps3gcmmemory.h" #include "gcmstate.h" #include "gcmlabels.h" #include "gcmdrawstate.h" #include "ps3/ps3_helpers.h" #include #include #include "tier0/memdbgon.h" #else #include "spumgr_spu.h" #include "gcmdrawstate.h" #endif //-------------------------------------------------------------------------------------------------- // Globals //-------------------------------------------------------------------------------------------------- ALIGN128 CGcmDrawState gGcmDrawState[GCM_DRAWSTATE_MAX] ALIGN128_POST; CGcmDrawState* gpGcmDrawState = &gGcmDrawState[0]; int g_bZcullAuto = 1; int g_nZcullDefault = 100; int g_nZcullMoveForward = 100; int g_nZcullPushBack = 100; SetVertexDataArrayCache_t g_cacheSetVertexDataArray[ D3D_MAX_STREAMS ]; vec_float4 g_aFPConst[GCM_DS_MAXFPCONST] = {0,}; vec_float4 g_aVPConst[GCM_DS_MAXVPCONST] = {0,}; D3DStreamDesc g_dxGcmVertexStreamSources[D3D_MAX_STREAMS]; uint32 g_UPHigh = 0; uint32 g_UPFrame; #ifndef SPU ALIGN16 uint8 g_aDynECB[GCM_DS_MAXDYNECB] ALIGN16_POST; // Ring buffer of dynamic cmds uint32 g_nDynECBIdx = 0; #endif #ifndef SPU ALIGN128 CGcmDrawState::FixedData gFixedData[GCM_DRAWSTATE_MAX] ALIGN128_POST; #else ALIGN128 CGcmDrawState::FixedData gFixedData[1] ALIGN128_POST; #endif #ifndef SPU ALIGN128 uint8 gPackData[GCM_DRAWSTATE_MAX][GCM_DS_MAXDATAPERDRAWCALL] ALIGN128_POST; #else ALIGN128 uint8 gPackData[1][GCM_DS_MAXDATAPERDRAWCALL] ALIGN128_POST; #endif //-------------------------------------------------------------------------------------------------- // DX lookups etc.. //-------------------------------------------------------------------------------------------------- // THese tables are auto-generated in dxabstract.cpp, UnpackD3DRSITable() // They provide renderstate classes and their default values.... uint8 g_d3drs_defvalue_indices[D3DRS_VALUE_LIMIT] = { 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}; uint32 g_d3drs_defvalues[11] = { 0x0, 0x31415926, 0x3, 0x2, 0x1, 0x7, 0x3F800000, 0x8, 0xFFFFFFFF, 0x42800000, 0xF }; uint16 dxtogl_blendop[7] = { /*invalid*/CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_ADD, CELL_GCM_FUNC_SUBTRACT, CELL_GCM_FUNC_REVERSE_SUBTRACT, CELL_GCM_MIN, CELL_GCM_MAX, /*invalid*/CELL_GCM_FUNC_ADD, }; uint32 dxtogl_stencilmode[10] = { /*invalid*/ CELL_GCM_KEEP, /*D3DSTENCILOP_KEEP*/ CELL_GCM_KEEP, /*D3DSTENCILOP_ZERO*/ CELL_GCM_ZERO, /*D3DSTENCILOP_REPLACE*/ CELL_GCM_REPLACE, /*D3DSTENCILOP_INCRSAT*/ CELL_GCM_INCR, /*D3DSTENCILOP_DECRSAT*/ CELL_GCM_DECR, /*D3DSTENCILOP_INVERT*/ CELL_GCM_INVERT, /*D3DSTENCILOP_INCR*/ CELL_GCM_INCR_WRAP, /*D3DSTENCILOP_DECR*/ CELL_GCM_DECR_WRAP, /*invalid*/ CELL_GCM_KEEP, }; // addressing modes // 1 D3DTADDRESS_WRAP Tile the texture at every integer junction. // D3DTADDRESS_MIRROR Similar to D3DTADDRESS_WRAP, except that the texture is flipped at every integer junction. // 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. // 4 D3DTADDRESS_BORDER Texture coordinates outside the range [0.0, 1.0] are set to the border color. // D3DTADDRESS_MIRRORONCE Similar to D3DTADDRESS_MIRROR and D3DTADDRESS_CLAMP. // Takes the absolute value of the texture coordinate (thus, mirroring around 0), // and then clamps to the maximum value. The most common usage is for volume textures, // where support for the full D3DTADDRESS_MIRRORONCE texture-addressing mode is not // necessary, but the data is symmetric around the one axis. uint8 dxtogl_addressMode[6] = { CELL_GCM_TEXTURE_WRAP, // no zero entry CELL_GCM_TEXTURE_WRAP, // from D3DTADDRESS_WRAP CELL_GCM_TEXTURE_MIRROR, // from D3DTADDRESS_MIRROR CELL_GCM_TEXTURE_CLAMP_TO_EDGE, // from D3DTADDRESS_CLAMP CELL_GCM_TEXTURE_BORDER, // from D3DTADDRESS_BORDER CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER, // no D3DTADDRESS_MIRRORONCE support }; uint8 dxtogl_anisoIndexHalf[32] = // indexed by [ dxsamp->maxAniso / 2 ] { CELL_GCM_TEXTURE_MAX_ANISO_1, // 0-1 CELL_GCM_TEXTURE_MAX_ANISO_2, // 2-3 CELL_GCM_TEXTURE_MAX_ANISO_4, // 4-5 CELL_GCM_TEXTURE_MAX_ANISO_6, // 6-7 CELL_GCM_TEXTURE_MAX_ANISO_8, // 8-9 CELL_GCM_TEXTURE_MAX_ANISO_10, // 10-11 CELL_GCM_TEXTURE_MAX_ANISO_12, // 12-13 CELL_GCM_TEXTURE_MAX_ANISO_16, // 14-15 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 16 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 18 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 20 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 22 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 24 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 26 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 28 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 30 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 32 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 34 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 36 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 38 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 40 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 42 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 44 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 46 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 48 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 50 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 52 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 54 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 56 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 58 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 60 CELL_GCM_TEXTURE_MAX_ANISO_16, // ... rest >= 62 }; uint8 dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter]. { /* mip filter ---------------> D3DTEXF_NONE D3DTEXF_POINT D3DTEXF_LINEAR (D3DTEXF_ANISOTROPIC not applicable to mip filter) */ /* 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 /* min = D3DTEXF_POINT */ { CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_NEAREST_NEAREST, CELL_GCM_TEXTURE_NEAREST_LINEAR, CELL_GCM_TEXTURE_NEAREST }, /* min = D3DTEXF_LINEAR */ { CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_LINEAR_NEAREST, CELL_GCM_TEXTURE_LINEAR_LINEAR, CELL_GCM_TEXTURE_NEAREST }, /* 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 }; uint8 dxtogl_magFilter[4] = // indexed by _D3DTEXTUREFILTERTYPE { CELL_GCM_TEXTURE_NEAREST, // D3DTEXF_NONE not applicable to mag filter but we handle it like POINT (mat_showmiplevels hits this) CELL_GCM_TEXTURE_NEAREST, // D3DTEXF_POINT CELL_GCM_TEXTURE_LINEAR, // D3DTEXF_LINEAR CELL_GCM_TEXTURE_LINEAR, // D3DTEXF_ANISOTROPIC (aniso will be driven by setting maxAniso, not by a GL filter mode) }; //-------------------------------------------------------------------------------------------------- // Send to SPU //-------------------------------------------------------------------------------------------------- #ifndef SPU int gSpuJobIssued = 0; uint32 gSpuStartIdx = 0; uint32 gSpuCount = 0; //-------------------------------------------------------------------------------------------------- // SPU DRAW CODE //-------------------------------------------------------------------------------------------------- #if !PPU_DRAW void CGcmDrawState::SendToSpu() { SpuTaskHandle *pTask = &g_ps3gcmGlobalState.m_spuHandle; // Get this drawcall indx and the next uint32 idx = gpGcmDrawState - gGcmDrawState; uint32 nextidx = (idx + 1) % GCM_DRAWSTATE_MAX; gSpuCount ++; // Move gpGcmDrawState to the next set of Data CGcmDrawState* pPrevDrawState = gpGcmDrawState; gpGcmDrawState = &gGcmDrawState[nextidx]; gpGcmDrawState->m_shaderVxConstants = pPrevDrawState->m_shaderVxConstants; gpGcmDrawState->m_pPixelShaderData = pPrevDrawState->m_pPixelShaderData; gpGcmDrawState->m_pVertexShaderData = pPrevDrawState->m_pVertexShaderData; gpGcmDrawState->m_nBackBufferSize[0] = pPrevDrawState->m_nBackBufferSize[0]; gpGcmDrawState->m_nBackBufferSize[1] = pPrevDrawState->m_nBackBufferSize[1]; gpGcmDrawState->m_pDataCursor = gpGcmDrawState->m_pData; gpGcmDrawState->m_dirtySamplersMask = 0; gpGcmDrawState->m_dirtyCachesMask = 0; gpGcmDrawState->m_dirtyStatesMask = 0; gpGcmDrawState->m_nFreeLabel = 0; memset(gpGcmDrawState->m_pFixed->m_aSamplerIdx, 0xff, sizeof(m_pFixed->m_aSamplerIdx)); gpGcmDrawState->m_pFixed->m_nSampler = 0; gpGcmDrawState->m_pFixed->m_nInstanced = 0; gpGcmDrawState->m_nNumECB = 0; memset(gpGcmDrawState->m_aECB, 0, sizeof(m_aECB)); if ( (gSpuCount < 4) && (m_cmd != CmdEndFrame) ) return; // Send the state(s) to the SPU // Wait on previous drawcall if (gSpuJobIssued) { uint32 fifoPosn; gSpuMgr.ReadMailbox(pTask, &fifoPosn); gpGcmContext->current = (uint32*)fifoPosn; } // Makesure we have 16K at least, per drawcall (we issue 4 calls at a time) cellGcmReserveMethodSizeInline(gpGcmContext, (GCM_DS_FIFOPERDRAW*GCM_NUMDRAWCALLS_SPU)/4); // 16K per draw call, /4 because api takes wordcount // Makesure FIFO is on a 16B boundary while (uintp(gpGcmContext->current) & 0xf) { *gpGcmContext->current = 0; gpGcmContext->current++; } // Build count and startidx parameter to send to SPU uint32 mailboxparam = (gSpuCount<<16) | gSpuStartIdx; //Send this drawstate m_eaOutputFIFO = (uint32)gpGcmContext->current; __asm ( "eieio" ); gSpuMgr.WriteMailbox(pTask, mailboxparam); gSpuJobIssued = 1; // If it's an endframe, wait for result now // comment out this if to always wait for the dma to come back if (m_cmd == CmdEndFrame) { uint32 fifoPosn; gSpuMgr.ReadMailbox(pTask, &fifoPosn); gpGcmContext->current = (uint32*)fifoPosn; gSpuJobIssued = 0; } gSpuStartIdx = nextidx; gSpuCount = 0; } #else // PPU_DRAW..... //-------------------------------------------------------------------------------------------------- // Draw on PPU //-------------------------------------------------------------------------------------------------- void CGcmDrawState::SendToSpu() { // Makesure we have 16K at least cellGcmReserveMethodSizeInline(gpGcmContext, GCM_DS_FIFOPERDRAW/4); // 16K per draw call // Makesure FIFO is on a 16B boundary while (uintp(gpGcmContext->current) & 0xf) { *gpGcmContext->current = 0; gpGcmContext->current++; } // Process cmd on PPU switch (m_cmd) { case CmdCommitStates: case CmdEndFrame: if (m_nFreeLabel) UnpackSetWriteBackEndLabel(GCM_LABEL_MEMORY_FREE, m_nFreeLabel); if ( m_dirtyStatesMask & kDirtyResetRsx) UnpackResetRsxState(); if (m_dirtyStatesMask & kDirtyZeroAllPSConsts) ZeroFPConsts(); if (m_dirtyStatesMask & kDirtyZeroAllVSConsts) ZeroVPConsts(); UnpackData(); // Pulls out pixel shader consts and sets vertex shader consts CommitRenderStates(); break; case CmdDrawPrim: { gpGcmDrawState->CommitAll((IDirect3DVertexDeclaration9 *)m_param[0], m_param[1]); // Draw GCM_FUNC( cellGcmSetDrawIndexArray, m_param[2], m_param[5], CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16, CELL_GCM_LOCATION_LOCAL, m_param[3] ); } break; case CmdDrawPrimUP: { D3DStreamDesc &dsd = g_dxGcmVertexStreamSources[0]; dsd.m_offset = 0; dsd.m_stride = m_param[2]; dsd.m_vtxBuffer = ( IDirect3DVertexBuffer9 * )( uintp )1; // invalid pointer, but non-NULL to signal it's a real vertex buffer; dsd.m_nLocalBufferOffset = 0; gpGcmDrawState->CommitAll((IDirect3DVertexDeclaration9 *)m_param[0], 0); GCM_FUNC(cellGcmSetCallCommand, m_param[1]); } break; } // Flip to the other set of Data if (gpGcmDrawState->m_pData == gPackData1) { gpGcmDrawState->m_pData = gPackData2; gpGcmDrawState->m_pFixed = &gFixedData2; } else { gpGcmDrawState->m_pData = gPackData1; gpGcmDrawState->m_pFixed = &gFixedData1; } gpGcmDrawState->m_pDataCursor = gpGcmDrawState->m_pData; m_dirtySamplersMask = 0; m_dirtyCachesMask = 0; m_dirtyStatesMask = 0; m_nFreeLabel = 0; memset(m_pFixed->m_aSamplerIdx, 0xff, sizeof(m_pFixed->m_aSamplerIdx)); m_pFixed->m_nSampler = 0; m_pFixed->m_nInstanced = 0; m_nNumECB = 0; memset(m_aECB, 0, sizeof(m_aECB)); } #endif // ndef SPU #endif //-------------------------------------------------------------------------------------------------- // test func to try to find corrupted ECBs //-------------------------------------------------------------------------------------------------- void CGcmDrawState::TestCommandBuffer( uint8 *pCmdBuf ) { uint8* pStart = pCmdBuf; uint8 *pReturnStack[20]; uint8 **pSP = &pReturnStack[ARRAYSIZE(pReturnStack)]; uint8 *pLastCmd; for(;;) { uint8 *pCmd=pCmdBuf; int nCmd = GetData( pCmdBuf ); if (nCmd > CBCMD_SET_VERTEX_SHADER_NEARZFARZ_STATE) DebuggerBreak(); switch( nCmd ) { case CBCMD_END: { if ( pSP == &pReturnStack[ARRAYSIZE(pReturnStack)] ) return; else { // pop pc pCmdBuf = *( pSP ++ ); break; } } case CBCMD_JUMP: pCmdBuf = GetData( pCmdBuf + sizeof( int ) ); break; case CBCMD_JSR: { Assert( pSP > &(pReturnStack[0] ) ); // *(--pSP ) = pCmdBuf + sizeof( int ) + sizeof( uint8 *); // pCmdBuf = GetData( pCmdBuf + sizeof( int ) ); TestCommandBuffer( GetData( pCmdBuf + sizeof( int ) ) ); pCmdBuf = pCmdBuf + sizeof( int ) + sizeof( uint8 *); break; } case CBCMD_SET_PIXEL_SHADER_FLOAT_CONST: { int nStartConst = GetData( pCmdBuf + sizeof( int ) ); int nNumConsts = GetData( pCmdBuf + 2 * sizeof( int ) ); pCmdBuf += nNumConsts * 4 * sizeof( float ) + 3 * sizeof( int ); break; } case CBCMD_SETPIXELSHADERFOGPARAMS: { Error("Pixel Shader Fog params not supported\n"); break; } case CBCMD_STORE_EYE_POS_IN_PSCONST: { pCmdBuf += 2 * sizeof( int ) + sizeof( float ); break; } case CBCMD_SET_DEPTH_FEATHERING_CONST: { // int nConst = GetData( pCmdBuf + sizeof( int ) ); // float fDepthBlendScale = GetData( pCmdBuf + 2 * sizeof( int ) ); pCmdBuf += 2 * sizeof( int ) + sizeof( float ); // SetDepthFeatheringPixelShaderConstant( nConst, fDepthBlendScale ); break; } case CBCMD_SET_VERTEX_SHADER_FLOAT_CONST: { int nStartConst = GetData( pCmdBuf + sizeof( int ) ); int nNumConsts = GetData( pCmdBuf + 2 * sizeof( int ) ); float const *pValues = reinterpret_cast< float const *> ( pCmdBuf + 3 * sizeof( int ) ); pCmdBuf += nNumConsts * 4 * sizeof( float ) + 3 * sizeof( int ); break; } case CBCMD_BIND_PS3_TEXTURE: { CPs3BindTexture_t tex = GetData (pCmdBuf + sizeof( int )); if (tex.m_pLmBlock->Offset() & 0x7e) DebuggerBreak(); pCmdBuf += sizeof(int) + sizeof(tex); break; } case CBCMD_BIND_PS3_STANDARD_TEXTURE: { CPs3BindTexture_t tex = GetData (pCmdBuf + sizeof( int )); if (m_pFixed->m_nInstanced) { uint32 nBindFlags = tex.m_nBindFlags; uint32 nSampler = tex.m_sampler; switch (tex.m_boundStd) { case TEXTURE_LOCAL_ENV_CUBEMAP: if (m_pFixed->m_nInstanced & GCM_DS_INST_ENVMAP) tex = m_pFixed->m_instanceEnvCubemap; break; case TEXTURE_LIGHTMAP: if (m_pFixed->m_nInstanced & GCM_DS_INST_LIGHTMAP) tex = m_pFixed->m_instanceLightmap; break; case TEXTURE_PAINT: if (m_pFixed->m_nInstanced & GCM_DS_INST_PAINTMAP) tex = m_pFixed->m_instancePaintmap; break; } tex.m_nBindFlags = nBindFlags; tex.m_sampler = nSampler; } // Test texture if (tex.m_pLmBlock->Offset() & 0x7e) DebuggerBreak(); pCmdBuf += sizeof(int) + sizeof(tex); break; } case CBCMD_PS3TEX: { pCmdBuf += sizeof(int) + (CBCMD_MAX_PS3TEX*sizeof(int)); break; } case CBCMD_LENGTH: { pCmdBuf += sizeof(int) *2 ; break; } case CBCMD_SET_PSHINDEX: { // int nIdx = GetData( pCmdBuf + sizeof( int ) ); // ShaderManager()->SetPixelShaderIndex( nIdx ); // pCmdBuf += 2 * sizeof( int ); Error("PSHINDEX Not Supported\n"); break; } case CBCMD_SET_VSHINDEX: { // int nIdx = GetData( pCmdBuf + sizeof( int ) ); // ShaderManager()->SetVertexShaderIndex( nIdx ); pCmdBuf += 2 * sizeof( int ); Error("VSHINDEX Not Supported\n"); break; } case CBCMD_SET_VERTEX_SHADER_FLASHLIGHT_STATE: { // int nStartConst = GetData( pCmdBuf + sizeof( int ) ); // SetVertexShaderConstantInternal( nStartConst, m_FlashlightWorldToTexture.Base(), 4, false ); // pCmdBuf += 2 * sizeof( int ); // Error("Flashlight unsupported\n"); pCmdBuf += 2 * sizeof( int ); break; } case CBCMD_SET_VERTEX_SHADER_NEARZFARZ_STATE: { Error("SetVertexShaderNearAndFarZ NOt SUPPORTED\n"); // int nStartConst = GetData( pCmdBuf + sizeof( int ) ); // // VMatrix m; // // m = m_MaterialProjectionMatrix; // // // GetMatrix( MATERIAL_PROJECTION, m.m[0] ); // // // m[2][2] = F/(N-F) (flip sign if RH) // // m[3][2] = NF/(N-F) // // float vNearFar[4]; // // float N = m[3][2] / m[2][2]; // float F = (m[3][2]*N) / (N + m[3][2]); // // vNearFar[0] = N; // vNearFar[1] = F; // // SetVertexShaderConstantInternal( nStartConst, vNearFar, 1, false ); pCmdBuf += 2 * sizeof( int ); break; } case CBCMD_SET_PIXEL_SHADER_FLASHLIGHT_STATE: { // int nLightSampler = GetData( pCmdBuf + sizeof( int ) ); // int nDepthSampler = GetData( pCmdBuf + 2 * sizeof( int ) ); // int nShadowNoiseSampler = GetData( pCmdBuf + 3 * sizeof( int ) ); // int nColorConst = GetData( pCmdBuf + 4 * sizeof( int ) ); // int nAttenConst = GetData( pCmdBuf + 5 * sizeof( int ) ); // int nOriginConst = GetData( pCmdBuf + 6 * sizeof( int ) ); // int nDepthTweakConst = GetData( pCmdBuf + 7 * sizeof( int ) ); // int nScreenScaleConst = GetData( pCmdBuf + 8 * sizeof( int ) ); // int nWorldToTextureConstant = GetData( pCmdBuf + 9 * sizeof( int ) ); // bool bFlashlightNoLambert = GetData( pCmdBuf + 10 * sizeof( int ) ) != 0; // bool bSinglePassFlashlight = GetData( pCmdBuf + 11 * sizeof( int ) ) != 0; // pCmdBuf += 12 * sizeof( int ); // // ShaderAPITextureHandle_t hTexture = g_pShaderUtil->GetShaderAPITextureBindHandle( m_FlashlightState.m_pSpotlightTexture, m_FlashlightState.m_nSpotlightTextureFrame, 0 ); // BindTexture( (Sampler_t)nLightSampler, TEXTURE_BINDFLAGS_SRGBREAD, hTexture ); // !!!BUG!!!srgb or not? // // SetPixelShaderConstantInternal( nAttenConst, m_pFlashlightAtten, 1, false ); // SetPixelShaderConstantInternal( nOriginConst, m_pFlashlightPos, 1, false ); // // 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 // // // DX10 hardware and single pass flashlight require a hack scalar since the flashlight is added in linear space // float flashlightColor[4] = { m_pFlashlightColor[0], m_pFlashlightColor[1], m_pFlashlightColor[2], m_pFlashlightColor[3] }; // if ( ( g_pHardwareConfig->UsesSRGBCorrectBlending() ) || ( bSinglePassFlashlight ) ) // { // // Magic number that works well on the 360 and NVIDIA 8800 // flashlightColor[0] *= 2.5f; // flashlightColor[1] *= 2.5f; // flashlightColor[2] *= 2.5f; // } // // SetPixelShaderConstantInternal( nColorConst, flashlightColor, 1, false ); // // if ( nWorldToTextureConstant >= 0 ) // { // SetPixelShaderConstantInternal( nWorldToTextureConstant, m_FlashlightWorldToTexture.Base(), 4, false ); // } // // BindStandardTexture( (Sampler_t)nShadowNoiseSampler, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D ); // if( m_pFlashlightDepthTexture && m_FlashlightState.m_bEnableShadows && ShaderUtil()->GetConfig().ShadowDepthTexture() ) // { // ShaderAPITextureHandle_t hDepthTexture = g_pShaderUtil->GetShaderAPITextureBindHandle( m_pFlashlightDepthTexture, 0, 0 ); // BindTexture( (Sampler_t)nDepthSampler, TEXTURE_BINDFLAGS_SHADOWDEPTH, hDepthTexture ); // // SetPixelShaderConstantInternal( nDepthTweakConst, m_pFlashlightTweaks, 1, false ); // // // Dimensions of screen, used for screen-space noise map sampling // float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0}; // int nWidth, nHeight; // BaseClass::GetBackBufferDimensions( nWidth, nHeight ); // // int nTexWidth, nTexHeight; // GetStandardTextureDimensions( &nTexWidth, &nTexHeight, TEXTURE_SHADOW_NOISE_2D ); // // vScreenScale[0] = (float) nWidth / nTexWidth; // vScreenScale[1] = (float) nHeight / nTexHeight; // vScreenScale[2] = 1.0f / m_FlashlightState.m_flShadowMapResolution; // vScreenScale[3] = 2.0f / m_FlashlightState.m_flShadowMapResolution; // SetPixelShaderConstantInternal( nScreenScaleConst, vScreenScale, 1, false ); // } // else // { // BindStandardTexture( (Sampler_t)nDepthSampler, TEXTURE_BINDFLAGS_NONE, TEXTURE_WHITE ); // } // Error("Flashlight unsupported\n"); pCmdBuf += 12 * sizeof( int ); break; } case CBCMD_SET_PIXEL_SHADER_UBERLIGHT_STATE: { // int iEdge0Const = GetData( pCmdBuf + sizeof( int ) ); // int iEdge1Const = GetData( pCmdBuf + 2 * sizeof( int ) ); // int iEdgeOOWConst = GetData( pCmdBuf + 3 * sizeof( int ) ); // int iShearRoundConst = GetData( pCmdBuf + 4 * sizeof( int ) ); // int iAABBConst = GetData( pCmdBuf + 5 * sizeof( int ) ); // int iWorldToLightConst = GetData( pCmdBuf + 6 * sizeof( int ) ); pCmdBuf += 7 * sizeof( int ); // // SetPixelShaderConstantInternal( iEdge0Const, m_UberlightRenderState.m_vSmoothEdge0.Base(), 1, false ); // SetPixelShaderConstantInternal( iEdge1Const, m_UberlightRenderState.m_vSmoothEdge1.Base(), 1, false ); // SetPixelShaderConstantInternal( iEdgeOOWConst, m_UberlightRenderState.m_vSmoothOneOverW.Base(), 1, false ); // SetPixelShaderConstantInternal( iShearRoundConst, m_UberlightRenderState.m_vShearRound.Base(), 1, false ); // SetPixelShaderConstantInternal( iAABBConst, m_UberlightRenderState.m_vaAbB.Base(), 1, false ); // SetPixelShaderConstantInternal( iWorldToLightConst, m_UberlightRenderState.m_WorldToLight.Base(), 4, false ); Error("Uberlight state unsupported\n"); break; } #ifndef NDEBUG default: Assert(0); break; #endif } pLastCmd = pCmd; } }