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

//================ 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 <materialsystem/imaterialsystem.h>
#include <vprof.h>
#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<int>( 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<uint8 *>( pCmdBuf + sizeof( int ) );
break;
case CBCMD_JSR:
{
Assert( pSP > &(pReturnStack[0] ) );
// *(--pSP ) = pCmdBuf + sizeof( int ) + sizeof( uint8 *);
// pCmdBuf = GetData<uint8 *>( pCmdBuf + sizeof( int ) );
TestCommandBuffer( GetData<uint8 *>( pCmdBuf + sizeof( int ) ) );
pCmdBuf = pCmdBuf + sizeof( int ) + sizeof( uint8 *);
break;
}
case CBCMD_SET_PIXEL_SHADER_FLOAT_CONST:
{
int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
int nNumConsts = GetData<int>( 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<int>( pCmdBuf + sizeof( int ) );
// float fDepthBlendScale = GetData<float>( pCmdBuf + 2 * sizeof( int ) );
pCmdBuf += 2 * sizeof( int ) + sizeof( float );
// SetDepthFeatheringPixelShaderConstant( nConst, fDepthBlendScale );
break;
}
case CBCMD_SET_VERTEX_SHADER_FLOAT_CONST:
{
int nStartConst = GetData<int>( pCmdBuf + sizeof( int ) );
int nNumConsts = GetData<int>( 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<CPs3BindTexture_t> (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<CPs3BindTexture_t> (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<int>( pCmdBuf + sizeof( int ) );
// ShaderManager()->SetPixelShaderIndex( nIdx );
// pCmdBuf += 2 * sizeof( int );
Error("PSHINDEX Not Supported\n");
break;
}
case CBCMD_SET_VSHINDEX:
{
// int nIdx = GetData<int>( 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<int>( 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<int>( 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<int>( pCmdBuf + sizeof( int ) );
// int nDepthSampler = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
// int nShadowNoiseSampler = GetData<int>( pCmdBuf + 3 * sizeof( int ) );
// int nColorConst = GetData<int>( pCmdBuf + 4 * sizeof( int ) );
// int nAttenConst = GetData<int>( pCmdBuf + 5 * sizeof( int ) );
// int nOriginConst = GetData<int>( pCmdBuf + 6 * sizeof( int ) );
// int nDepthTweakConst = GetData<int>( pCmdBuf + 7 * sizeof( int ) );
// int nScreenScaleConst = GetData<int>( pCmdBuf + 8 * sizeof( int ) );
// int nWorldToTextureConstant = GetData<int>( pCmdBuf + 9 * sizeof( int ) );
// bool bFlashlightNoLambert = GetData<int>( pCmdBuf + 10 * sizeof( int ) ) != 0;
// bool bSinglePassFlashlight = GetData<int>( 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<int>( pCmdBuf + sizeof( int ) );
// int iEdge1Const = GetData<int>( pCmdBuf + 2 * sizeof( int ) );
// int iEdgeOOWConst = GetData<int>( pCmdBuf + 3 * sizeof( int ) );
// int iShearRoundConst = GetData<int>( pCmdBuf + 4 * sizeof( int ) );
// int iAABBConst = GetData<int>( pCmdBuf + 5 * sizeof( int ) );
// int iWorldToLightConst = GetData<int>( 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;
}
}