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
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;
|
|
}
|
|
}
|