diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index e62bb722d9..5f06011f0d 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -663,8 +663,10 @@ void hleEnterVblank(u64 userdata, int cyclesLate) { // Sometimes users just think the sound emulation is broken. static bool hasNotifiedSlow = false; if (!g_Config.bHideSlowWarnings && !hasNotifiedSlow && IsRunningSlow()) { +#ifndef _DEBUG I18NCategory *err = GetI18NCategory("Error"); host->NotifyUserMessage(err->T("Running slow: try frameskip, sound is choppy when slow"), 6.0f, 0xFF3030FF); +#endif hasNotifiedSlow = true; } diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index f8c19104a6..c817098256 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -66,348 +66,32 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" -enum { - FLAG_FLUSHBEFORE = 1, - FLAG_FLUSHBEFOREONCHANGE = 2, - FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. - FLAG_EXECUTEONCHANGE = 8, - FLAG_READS_PC = 16, - FLAG_WRITES_PC = 32, - FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both! -}; - -struct CommandTableEntry { +struct D3D11CommandTableEntry { uint8_t cmd; uint8_t flags; uint64_t dirty; GPU_D3D11::CmdFunc func; }; -static const CommandTableEntry commandTable[] = { - // Changes that dirty the framebuffer - { GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE }, - - // Changes that dirty uniforms - { GE_CMD_FOGCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOLOR }, - { GE_CMD_FOG1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, - { GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, - - // Should these maybe flush? - { GE_CMD_MINZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, - { GE_CMD_MAXZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, - - // Changes that dirty texture scaling. - { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, - { GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV }, - { GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU }, - { GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetV }, - +static const D3D11CommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_TexSize0 }, - { GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXLEVEL, 0, DIRTY_TEXTURE_PARAMS }, // Flushing on this is EXPENSIVE in Gran Turismo and of little use - { GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXBUFWIDTH1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These must flush on change, so that LoadClut doesn't have to always flush. - { GE_CMD_CLUTADDR, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTADDRUPPER, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These affect the fragment shader so need flushing. - { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK }, - - // These change the vertex shader so need flushing. - { GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE }, - - // This changes both shaders so need flushing. - { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - - // Uniform changes - { GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK }, - { GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF }, - { GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXENV }, - - // Simple render state changes. Handled in StateMapping.cpp. - { GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_FOGCOEF }, // These are combined in D3D11 - { GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // These can't be emulated in D3D (except a few special cases) - { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Can probably ignore this one as we don't support AA lines. - { GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Morph weights. TODO: Remove precomputation? - { GE_CMD_MORPHWEIGHT0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT2, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT4, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT5, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT6, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT7, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - - // Control spline/bezier patches. Don't really require flushing as such, but meh. - { GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Viewport. - { GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Region - { GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_REGION2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Scissor - { GE_CMD_SCISSOR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_SCISSOR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Lighting base colors - { GE_CMD_AMBIENTCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_AMBIENTALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_MATERIALDIFFUSE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATDIFFUSE }, - { GE_CMD_MATERIALEMISSIVE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATEMISSIVE }, - { GE_CMD_MATERIALAMBIENT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALSPECULAR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - { GE_CMD_MATERIALSPECULARCOEF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - - // Light parameters - { GE_CMD_LX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LDX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKA0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKB0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKA1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKB1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKA2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKB2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKA3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LKB3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LKC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKS0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKS1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKS2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKS3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKO0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKO1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKO2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKO3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LAC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LSC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LAC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LSC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LAC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LSC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LAC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - // Ignored commands - { GE_CMD_TEXFLUSH, 0 }, - { GE_CMD_TEXLODSLOPE, 0 }, - { GE_CMD_TEXSYNC, 0 }, - - // These are just nop or part of other later commands. - { GE_CMD_NOP, 0 }, - { GE_CMD_BASE, 0 }, - { GE_CMD_TRANSFERSRC, 0 }, - { GE_CMD_TRANSFERSRCW, 0 }, - { GE_CMD_TRANSFERDST, 0 }, - { GE_CMD_TRANSFERDSTW, 0 }, - { GE_CMD_TRANSFERSRCPOS, 0 }, - { GE_CMD_TRANSFERDSTPOS, 0 }, - { GE_CMD_TRANSFERSIZE, 0 }, - - // From Common. No flushing but definitely need execute. - { GE_CMD_OFFSETADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_OffsetAddr }, - { GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_Origin }, - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Prim }, - { GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Jump }, - { GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Call }, - { GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Ret }, - { GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_End }, - { GE_CMD_VADDR, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Vaddr }, - { GE_CMD_IADDR, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Iaddr }, - { GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPU_D3D11::Execute_BJump }, // EXECUTE - { GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to? // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_D3D11::Execute_VertexType }, + { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Prim }, { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Bezier }, { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_Spline }, - // These two are actually processed in CMD_END. - { GE_CMD_SIGNAL, FLAG_FLUSHBEFORE }, - { GE_CMD_FINISH, FLAG_FLUSHBEFORE }, - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_LoadClut }, { GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart }, - - // We don't use the dither table. - { GE_CMD_DITH0 }, - { GE_CMD_DITH1 }, - { GE_CMD_DITH2 }, - { GE_CMD_DITH3 }, - - // These handle their own flushing. - { GE_CMD_WORLDMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_WorldMtxNum }, - { GE_CMD_WORLDMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_WorldMtxData }, - { GE_CMD_VIEWMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ViewMtxNum }, - { GE_CMD_VIEWMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ViewMtxData }, - { GE_CMD_PROJMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ProjMtxNum }, - { GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData }, - { GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum }, - { GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData }, - { GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BoneMtxNum }, - { GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData }, - - // Vertex Screen/Texture/Color - { GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - - // "Missing" commands (gaps in the sequence) - { GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_0D, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_11, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_29, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_34, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_35, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_39, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_4E, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_4F, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_52, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_59, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_5A, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_B6, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_B7, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_D1, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_ED, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_EF, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FA, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FB, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FD, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FE, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - // Appears to be debugging related or something? Hit a lot in GoW. - { GE_CMD_UNKNOWN_FF, 0 }, }; -GPU_D3D11::CommandInfo GPU_D3D11::cmdInfo_[256]; +GPU_D3D11::CommandInfo GPU_D3D11::cmdInfo_[256]{}; GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) : GPUCommon(gfxCtx, draw), drawEngine_(draw, @@ -444,9 +128,24 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - // Sanity check cmdInfo_ table - no dupes please - std::set dupeCheck; memset(cmdInfo_, 0, sizeof(cmdInfo_)); + + // Import both the global and local command tables, and check for dupes + std::set dupeCheck; + for (size_t i = 0; i < commonCommandTableSize; i++) { + const u8 cmd = commonCommandTable[i].cmd; + if (dupeCheck.find(cmd) != dupeCheck.end()) { + ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); + } else { + dupeCheck.insert(cmd); + } + cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); + cmdInfo_[cmd].func = commonCommandTable[i].func; + if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { + Crash(); + } + } + for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { const u8 cmd = commandTable[i].cmd; if (dupeCheck.find(cmd) != dupeCheck.end()) { @@ -460,6 +159,7 @@ GPU_D3D11::GPU_D3D11(GraphicsContext *gfxCtx, Draw::DrawContext *draw) Crash(); } } + // Find commands missing from the table. for (int i = 0; i < 0xEF; i++) { if (dupeCheck.find((u8)i) == dupeCheck.end()) { diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 062bbd527b..c025319492 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -50,345 +50,29 @@ namespace DX9 { -enum { - FLAG_FLUSHBEFORE = 1, - FLAG_FLUSHBEFOREONCHANGE = 2, - FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. - FLAG_EXECUTEONCHANGE = 8, - FLAG_READS_PC = 16, - FLAG_WRITES_PC = 32, - FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both! -}; - -struct CommandTableEntry { +struct D3D9CommandTableEntry { uint8_t cmd; uint8_t flags; uint64_t dirty; GPU_DX9::CmdFunc func; }; -static const CommandTableEntry commandTable[] = { - // Changes that dirty the framebuffer - { GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - {GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE}, - - // Changes that dirty uniforms - {GE_CMD_FOGCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOLOR}, - {GE_CMD_FOG1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF}, - {GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF}, - - // Should these maybe flush? - {GE_CMD_MINZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE}, - {GE_CMD_MAXZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE}, - - // Changes that dirty texture scaling. - { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, - { GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV }, - { GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU }, - { GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetV }, - +static const D3D9CommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_TexSize0 }, - { GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXLEVEL, FLAG_EXECUTEONCHANGE, DIRTY_TEXTURE_PARAMS, &GPUCommon::Execute_TexLevel }, - { GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXBUFWIDTH1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These must flush on change, so that LoadClut doesn't have to always flush. - { GE_CMD_CLUTADDR, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTADDRUPPER, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These affect the fragment shader so need flushing. - {GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK}, - - // These change the vertex shader so need flushing. - {GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE}, - - // This changes both shaders so need flushing. - { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - - // Uniform changes - { GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK }, - { GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF }, - { GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXENV }, - - // Simple render state changes. Handled in StateMapping.cpp. - {GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE}, - {GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // These can't be emulated in D3D (except a few special cases) - {GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Can probably ignore this one as we don't support AA lines. - {GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Morph weights. TODO: Remove precomputation? - {GE_CMD_MORPHWEIGHT0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT2, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT4, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT5, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT6, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT7, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - - // Control spline/bezier patches. Don't really require flushing as such, but meh. - {GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Viewport. - { GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Region - { GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_REGION2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Scissor - { GE_CMD_SCISSOR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_SCISSOR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Lighting base colors - { GE_CMD_AMBIENTCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_AMBIENTALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_MATERIALDIFFUSE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATDIFFUSE }, - { GE_CMD_MATERIALEMISSIVE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATEMISSIVE }, - { GE_CMD_MATERIALAMBIENT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALSPECULAR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - { GE_CMD_MATERIALSPECULARCOEF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - - // Light parameters - {GE_CMD_LX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LDX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKA0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKB0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKA1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKB1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKA2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKB2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKA3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LKB3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LKC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKS0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKS1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKS2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKS3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKO0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKO1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKO2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKO3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LAC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LSC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LAC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LSC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LAC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LSC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LAC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - // Ignored commands - {GE_CMD_TEXFLUSH, 0}, - {GE_CMD_TEXLODSLOPE, 0}, - {GE_CMD_TEXSYNC, 0}, - - // These are just nop or part of other later commands. - {GE_CMD_NOP, 0}, - {GE_CMD_BASE, 0}, - {GE_CMD_TRANSFERSRC, 0}, - {GE_CMD_TRANSFERSRCW, 0}, - {GE_CMD_TRANSFERDST, 0}, - {GE_CMD_TRANSFERDSTW, 0}, - {GE_CMD_TRANSFERSRCPOS, 0}, - {GE_CMD_TRANSFERDSTPOS, 0}, - {GE_CMD_TRANSFERSIZE, 0}, - - // From Common. No flushing but definitely need execute. - {GE_CMD_OFFSETADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_OffsetAddr}, - {GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_Origin}, - {GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Prim}, - {GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Jump}, - {GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Call}, - {GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Ret}, - {GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_End}, - {GE_CMD_VADDR, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Vaddr}, - {GE_CMD_IADDR, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Iaddr}, - {GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPU_DX9::Execute_BJump}, // EXECUTE - {GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_DX9::Execute_BoundingBox}, // + FLUSHBEFORE when we implement... or not, do we need to? + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE }, // Changing the vertex type requires us to flush. - {GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_DX9::Execute_VertexType}, + { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_DX9::Execute_VertexType }, - {GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Bezier}, - {GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Spline}, - - // These two are actually processed in CMD_END. - {GE_CMD_SIGNAL, FLAG_FLUSHBEFORE}, - {GE_CMD_FINISH, FLAG_FLUSHBEFORE}, + { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_DX9::Execute_Prim }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - {GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_LoadClut}, - {GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart}, - - // We don't use the dither table. - {GE_CMD_DITH0}, - {GE_CMD_DITH1}, - {GE_CMD_DITH2}, - {GE_CMD_DITH3}, - - // These handle their own flushing. - {GE_CMD_WORLDMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_WorldMtxNum}, - {GE_CMD_WORLDMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_WorldMtxData}, - {GE_CMD_VIEWMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ViewMtxNum}, - {GE_CMD_VIEWMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ViewMtxData}, - {GE_CMD_PROJMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ProjMtxNum}, - {GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData}, - {GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum}, - {GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData}, - {GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BoneMtxNum}, - {GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData}, - - // Vertex Screen/Texture/Color - { GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - { GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - - // "Missing" commands (gaps in the sequence) - {GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_0D, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_11, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_29, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_34, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_35, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_39, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_4E, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_4F, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_52, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_59, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_5A, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_B6, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_B7, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_D1, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_ED, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_EF, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FA, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FB, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FD, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FE, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - // Appears to be debugging related or something? Hit a lot in GoW. - { GE_CMD_UNKNOWN_FF, 0 }, + { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_LoadClut }, + { GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart }, }; GPU_DX9::CommandInfo GPU_DX9::cmdInfo_[256]; @@ -426,9 +110,24 @@ GPU_DX9::GPU_DX9(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - // Sanity check cmdInfo_ table - no dupes please - std::set dupeCheck; memset(cmdInfo_, 0, sizeof(cmdInfo_)); + + // Import both the global and local command tables, and check for dupes + std::set dupeCheck; + for (size_t i = 0; i < commonCommandTableSize; i++) { + const u8 cmd = commonCommandTable[i].cmd; + if (dupeCheck.find(cmd) != dupeCheck.end()) { + ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); + } else { + dupeCheck.insert(cmd); + } + cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); + cmdInfo_[cmd].func = commonCommandTable[i].func; + if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { + Crash(); + } + } + for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { const u8 cmd = commandTable[i].cmd; if (dupeCheck.find(cmd) != dupeCheck.end()) { diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 8f5815d63a..70c0cf12d7 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -52,17 +52,7 @@ #include "Windows/GPU/WindowsGLContext.h" #endif -enum { - FLAG_FLUSHBEFORE = 1, - FLAG_FLUSHBEFOREONCHANGE = 2, - FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. - FLAG_EXECUTEONCHANGE = 8, - FLAG_READS_PC = 16, - FLAG_WRITES_PC = 32, - // No flag for dirtying needed - if the dirty flag is non zero, it's "on change". -}; - -struct CommandTableEntry { +struct GLESCommandTableEntry { uint8_t cmd; uint8_t flags; uint64_t dirty; @@ -71,325 +61,22 @@ struct CommandTableEntry { // This table gets crunched into a faster form by init. // TODO: Share this table between the backends. Will have to make another indirection for the function pointers though.. -static const CommandTableEntry commandTable[] = { - // Changes that dirty the framebuffer - {GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE}, - - // Changes that dirty uniforms - {GE_CMD_FOGCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOLOR}, - {GE_CMD_FOG1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF}, - {GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF}, - - // Should these maybe flush? - {GE_CMD_MINZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE}, - {GE_CMD_MAXZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE}, - - {GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, 0}, - {GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU}, - {GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV}, - {GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU}, - {GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetV}, - +static const GLESCommandTableEntry commandTable[] = { // Changes that dirty the current texture. - {GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, DIRTY_UVSCALEOFFSET, &GPU_GLES::Execute_TexSize0}, - {GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE}, - {GE_CMD_TEXLEVEL, FLAG_EXECUTEONCHANGE, DIRTY_TEXTURE_PARAMS, &GPUCommon::Execute_TexLevel}, - {GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE|DIRTY_UVSCALEOFFSET}, - {GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXADDR7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE}, - {GE_CMD_TEXBUFWIDTH1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXBUFWIDTH7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - // These must flush on change, so that LoadClut doesn't have to always flush. - {GE_CMD_CLUTADDR, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CLUTADDRUPPER, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CLUTFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, + { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, DIRTY_UVSCALEOFFSET, &GPU_GLES::Execute_TexSize0 }, - // These affect the fragment shader so need flushing. - {GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK}, - - // These change the vertex shader so need flushing. - {GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE}, - - // This changes both shaders so need flushing. - {GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - {GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS}, - - // Uniform changes - {GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK}, - {GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF}, - {GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXENV}, - - // Simple render state changes. Handled in StateMapping.cpp. - {GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE}, - {GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Can probably ignore this one as we don't support AA lines. - {GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Morph weights. - {GE_CMD_MORPHWEIGHT0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT2, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT4, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT5, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT6, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - {GE_CMD_MORPHWEIGHT7, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight}, - - // Control spline/bezier patches. Don't really require flushing as such, but meh. - {GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE}, - {GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Viewport. - {GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX}, - {GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX}, - {GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE}, - - // Region - {GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_REGION2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - - // Scissor - {GE_CMD_SCISSOR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - {GE_CMD_SCISSOR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS}, - - // Lighting base colors - {GE_CMD_AMBIENTCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT}, - {GE_CMD_AMBIENTALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT}, - {GE_CMD_MATERIALDIFFUSE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATDIFFUSE}, - {GE_CMD_MATERIALEMISSIVE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATEMISSIVE}, - {GE_CMD_MATERIALAMBIENT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA}, - {GE_CMD_MATERIALALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA}, - {GE_CMD_MATERIALSPECULAR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR}, - {GE_CMD_MATERIALSPECULARCOEF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR}, - - // Light parameters - {GE_CMD_LX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LDX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKA0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKB0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKA1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKB1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKA2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKB2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKA3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LKB3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LKC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKS0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKS1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKS2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKS3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LKO0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LKO1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LKO2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LKO3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - {GE_CMD_LAC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LDC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LSC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0}, - {GE_CMD_LAC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LDC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LSC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1}, - {GE_CMD_LAC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LDC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LSC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2}, - {GE_CMD_LAC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LDC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - {GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3}, - - // Ignored commands - {GE_CMD_TEXFLUSH, 0}, - {GE_CMD_TEXLODSLOPE, 0}, - {GE_CMD_TEXSYNC, 0}, - - // These are just nop or part of other later commands. - {GE_CMD_NOP, 0}, - {GE_CMD_BASE, 0}, - {GE_CMD_TRANSFERSRC, 0}, - {GE_CMD_TRANSFERSRCW, 0}, - {GE_CMD_TRANSFERDST, 0}, - {GE_CMD_TRANSFERDSTW, 0}, - {GE_CMD_TRANSFERSRCPOS, 0}, - {GE_CMD_TRANSFERDSTPOS, 0}, - {GE_CMD_TRANSFERSIZE, 0}, - - // From Common. No flushing but definitely need execute. - {GE_CMD_OFFSETADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_OffsetAddr}, - {GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_Origin}, - {GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_GLES::Execute_Prim}, - {GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Jump}, - {GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Call}, - {GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Ret}, - {GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_End}, // Flush? - {GE_CMD_VADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Vaddr}, - {GE_CMD_IADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Iaddr}, - {GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BJump}, // EXECUTE - {GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPU_GLES::Execute_BoundingBox}, // + FLUSHBEFORE when we implement... or not, do we need to? + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE}, // Changing the vertex type requires us to flush. - {GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_GLES::Execute_VertexType}, + { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_GLES::Execute_VertexType }, - {GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Bezier}, - {GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Spline}, - - // These two are actually processed in CMD_END. - {GE_CMD_SIGNAL, FLAG_FLUSHBEFORE}, - {GE_CMD_FINISH, FLAG_FLUSHBEFORE}, + { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_GLES::Execute_Prim }, + { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Bezier }, + { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_Spline }, // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... - {GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_LoadClut}, - {GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart}, - - // We don't use the dither table. - {GE_CMD_DITH0}, - {GE_CMD_DITH1}, - {GE_CMD_DITH2}, - {GE_CMD_DITH3}, - - // These handle their own flushing. - {GE_CMD_WORLDMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_WorldMtxNum}, - {GE_CMD_WORLDMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_WorldMtxData}, - {GE_CMD_VIEWMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ViewMtxNum}, - {GE_CMD_VIEWMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ViewMtxData}, - {GE_CMD_PROJMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ProjMtxNum}, - {GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData}, - {GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum}, - {GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData}, - {GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BoneMtxNum}, - {GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData}, - - // Vertex Screen/Texture/Color - {GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - - // "Missing" commands (gaps in the sequence) - {GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_0D, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_11, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_29, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_34, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_35, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_39, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_4E, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_4F, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_52, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_59, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_5A, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_B6, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_B7, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_D1, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_ED, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_EF, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FA, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FB, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FD, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - {GE_CMD_UNKNOWN_FE, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown}, - // Appears to be debugging related or something? Hit a lot in GoW. - {GE_CMD_UNKNOWN_FF, 0}, + { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_GLES::Execute_LoadClut }, + { GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart }, }; GPU_GLES::CommandInfo GPU_GLES::cmdInfo_[256]; @@ -427,9 +114,24 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - // Sanity check cmdInfo_ table - no dupes please - std::set dupeCheck; memset(cmdInfo_, 0, sizeof(cmdInfo_)); + + // Import both the global and local command tables, and check for dupes + std::set dupeCheck; + for (size_t i = 0; i < commonCommandTableSize; i++) { + const u8 cmd = commonCommandTable[i].cmd; + if (dupeCheck.find(cmd) != dupeCheck.end()) { + ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); + } else { + dupeCheck.insert(cmd); + } + cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); + cmdInfo_[cmd].func = commonCommandTable[i].func; + if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { + Crash(); + } + } + for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { const u8 cmd = commandTable[i].cmd; if (dupeCheck.find(cmd) != dupeCheck.end()) { diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index c9106b5b06..eb119ce02e 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -26,6 +26,313 @@ #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/DrawEngineCommon.h" +const CommonCommandTableEntry commonCommandTable[] = { + // From Common. No flushing but definitely need execute. + { GE_CMD_OFFSETADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_OffsetAddr }, + { GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_Origin }, + { GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Jump }, + { GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Call }, + { GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Ret }, + { GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_End }, + { GE_CMD_VADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Vaddr }, + { GE_CMD_IADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Iaddr }, + { GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BJump }, // EXECUTE + { GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to? + + // Changes that dirty the framebuffer + { GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE }, + + { GE_CMD_FOGCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOLOR }, + { GE_CMD_FOG1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, + { GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, + + // These affect the fragment shader so need flushing. + { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK }, + + // These change the vertex shader so need flushing. + { GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE }, + + // These change both shaders so need flushing. + { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + + // Uniform changes + { GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK }, + { GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF }, + { GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXENV }, + + // Simple render state changes. Handled in StateMapping.cpp. + { GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE }, + + { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, 0 }, + { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, + { GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV }, + { GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU }, + { GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetV }, + + // TEXSIZE0 is handled by each backend. + { GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, + { GE_CMD_TEXLEVEL, FLAG_EXECUTEONCHANGE, DIRTY_TEXTURE_PARAMS, &GPUCommon::Execute_TexLevel }, + { GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET }, + { GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXADDR7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, + { GE_CMD_TEXBUFWIDTH1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + { GE_CMD_TEXBUFWIDTH7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + + // These must flush on change, so that LoadClut doesn't have to always flush. + { GE_CMD_CLUTADDR, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CLUTADDRUPPER, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CLUTFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, + + // Morph weights. TODO: Remove precomputation? + { GE_CMD_MORPHWEIGHT0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT2, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT4, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT5, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT6, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + { GE_CMD_MORPHWEIGHT7, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, + + // Control spline/bezier patches. Don't really require flushing as such, but meh. + { GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE }, + + // These can't be emulated in D3D (except a few special cases) + { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE }, + + // Can probably ignore this one as we don't support AA lines. + { GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE }, + + // Viewport. + { GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, + { GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, + { GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE }, + + // Z clip + { GE_CMD_MINZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, + { GE_CMD_MAXZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, + + // Region + { GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_REGION2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + + // Scissor + { GE_CMD_SCISSOR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_SCISSOR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + + // Lighting base colors + { GE_CMD_AMBIENTCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, + { GE_CMD_AMBIENTALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, + { GE_CMD_MATERIALDIFFUSE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATDIFFUSE }, + { GE_CMD_MATERIALEMISSIVE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATEMISSIVE }, + { GE_CMD_MATERIALAMBIENT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, + { GE_CMD_MATERIALALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, + { GE_CMD_MATERIALSPECULAR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, + { GE_CMD_MATERIALSPECULARCOEF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, + + // Light parameters + { GE_CMD_LX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + { GE_CMD_LDX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LDY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LDZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LDX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LDY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LDZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LDX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LDY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LDZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LDX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LDY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LDZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + { GE_CMD_LKA0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LKB0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LKC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LKA1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LKB1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LKC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LKA2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LKB2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LKC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LKA3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LKB3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LKC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + { GE_CMD_LKS0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LKS1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LKS2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LKS3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + { GE_CMD_LKO0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LKO1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LKO2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LKO3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + { GE_CMD_LAC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LDC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LSC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, + { GE_CMD_LAC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LDC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LSC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, + { GE_CMD_LAC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LDC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LSC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, + { GE_CMD_LAC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LDC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + { GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, + + // Ignored commands + { GE_CMD_TEXFLUSH, 0 }, + { GE_CMD_TEXLODSLOPE, 0 }, + { GE_CMD_TEXSYNC, 0 }, + + // These are just nop or part of other later commands. + { GE_CMD_NOP, 0 }, + { GE_CMD_BASE, 0 }, + { GE_CMD_TRANSFERSRC, 0 }, + { GE_CMD_TRANSFERSRCW, 0 }, + { GE_CMD_TRANSFERDST, 0 }, + { GE_CMD_TRANSFERDSTW, 0 }, + { GE_CMD_TRANSFERSRCPOS, 0 }, + { GE_CMD_TRANSFERDSTPOS, 0 }, + { GE_CMD_TRANSFERSIZE, 0 }, + + // We don't use the dither table. + { GE_CMD_DITH0 }, + { GE_CMD_DITH1 }, + { GE_CMD_DITH2 }, + { GE_CMD_DITH3 }, + + // These handle their own flushing. + { GE_CMD_WORLDMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_WorldMtxNum }, + { GE_CMD_WORLDMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_WorldMtxData }, + { GE_CMD_VIEWMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ViewMtxNum }, + { GE_CMD_VIEWMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ViewMtxData }, + { GE_CMD_PROJMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ProjMtxNum }, + { GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData }, + { GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum }, + { GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData }, + { GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BoneMtxNum }, + { GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoneMtxData }, + + // Vertex Screen/Texture/Color + { GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + + // "Missing" commands (gaps in the sequence) + { GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_0D, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_11, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_29, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_34, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_35, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_39, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_4E, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_4F, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_52, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_59, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_5A, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_B6, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_B7, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_D1, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_ED, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_EF, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_FA, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_FB, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_FC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_FD, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + { GE_CMD_UNKNOWN_FE, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, + // Appears to be debugging related or something? Hit a lot in GoW. + { GE_CMD_UNKNOWN_FF, 0 }, +}; +size_t commonCommandTableSize = ARRAY_SIZE(commonCommandTable); + void GPUCommon::Flush() { drawEngineCommon_->DispatchFlush(); } diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 35d4553f56..6f41169786 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -30,6 +30,16 @@ enum DrawType { DRAW_BEZIER, }; +enum { + FLAG_FLUSHBEFORE = 1, + FLAG_FLUSHBEFOREONCHANGE = 2, + FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. + FLAG_EXECUTEONCHANGE = 8, + FLAG_READS_PC = 16, + FLAG_WRITES_PC = 32, + FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both! +}; + class GPUCommon : public GPUThreadEventQueue, public GPUDebugInterface { public: GPUCommon(GraphicsContext *gfxCtx, Draw::DrawContext *draw); @@ -206,6 +216,8 @@ public: return "N/A"; } + typedef void (GPUCommon::*CmdFunc)(u32 op, u32 diff); + protected: void SetDrawType(DrawType type) { if (type != lastDraw_) { @@ -348,3 +360,13 @@ private: double timeSteppingStarted_; double timeSpentStepping_; }; + +struct CommonCommandTableEntry { + uint8_t cmd; + uint8_t flags; + uint64_t dirty; + GPUCommon::CmdFunc func; +}; + +extern const CommonCommandTableEntry commonCommandTable[]; +extern size_t commonCommandTableSize; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 43028cf859..a635a268c5 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -46,17 +46,7 @@ #include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" -enum { - FLAG_FLUSHBEFORE = 1, - FLAG_FLUSHBEFOREONCHANGE = 2, - FLAG_EXECUTE = 4, // needs to actually be executed. unused for now. - FLAG_EXECUTEONCHANGE = 8, - FLAG_READS_PC = 16, - FLAG_WRITES_PC = 32, - FLAG_DIRTYONCHANGE = 64, // NOTE: Either this or FLAG_EXECUTE*, not both! -}; - -struct CommandTableEntry { +struct VulkanCommandTableEntry { uint8_t cmd; uint8_t flags; uint64_t dirty; @@ -67,326 +57,22 @@ GPU_Vulkan::CommandInfo GPU_Vulkan::cmdInfo_[256]; // This table gets crunched into a faster form by init. // TODO: Share this table between the backends. Will have to make another indirection for the function pointers though.. -static const CommandTableEntry commandTable[] = { - // Changes that dirty the framebuffer - { GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE }, - - // Changes that dirty uniforms - { GE_CMD_FOGCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOLOR }, - { GE_CMD_FOG1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, - { GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, - - // Should these maybe flush? - { GE_CMD_MINZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, - { GE_CMD_MAXZ, FLAG_FLUSHBEFOREONCHANGE, DIRTY_DEPTHRANGE }, - - // Changes that dirty texture scaling. - { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, - { GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV }, - { GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU }, - { GE_CMD_TEXOFFSETV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetV }, - +static const VulkanCommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_TexSize0 }, - { GE_CMD_TEXSIZE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSIZE7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXLEVEL, FLAG_EXECUTEONCHANGE, DIRTY_TEXTURE_PARAMS, &GPUCommon::Execute_TexLevel }, - { GE_CMD_TEXADDR0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE | DIRTY_UVSCALEOFFSET }, - { GE_CMD_TEXADDR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXADDR7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_IMAGE }, - { GE_CMD_TEXBUFWIDTH1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH4, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH5, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH6, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXBUFWIDTH7, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These must flush on change, so that LoadClut doesn't have to always flush. - { GE_CMD_CLUTADDR, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTADDRUPPER, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CLUTFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - // These affect the fragment shader so need flushing. - { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK }, - - // These change the vertex shader so need flushing. - { GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE }, - - // This changes both shaders so need flushing. - { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - - // Uniform changes - { GE_CMD_ALPHATEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF | DIRTY_ALPHACOLORMASK }, - { GE_CMD_COLORREF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORREF }, - { GE_CMD_TEXENVCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXENV }, - - // Simple render state changes. Handled in StateMapping.cpp. - { GE_CMD_OFFSETX, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_OFFSETY, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE }, - { GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Can probably ignore this one as we don't support AA lines. - { GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Morph weights. TODO: Remove precomputation? - { GE_CMD_MORPHWEIGHT0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT1, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT2, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT3, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT4, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT5, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT6, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - { GE_CMD_MORPHWEIGHT7, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_MorphWeight }, - - // Control spline/bezier patches. Don't really require flushing as such, but meh. - { GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Viewport. - { GE_CMD_VIEWPORTXSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTXCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTYCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_VIEWPORTZSCALE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_VIEWPORTZCENTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_DEPTHRANGE | DIRTY_PROJMATRIX }, - { GE_CMD_CLIPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - - // Region - { GE_CMD_REGION1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_REGION2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Scissor - { GE_CMD_SCISSOR1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_SCISSOR2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - - // Lighting base colors - { GE_CMD_AMBIENTCOLOR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_AMBIENTALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_AMBIENT }, - { GE_CMD_MATERIALDIFFUSE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATDIFFUSE }, - { GE_CMD_MATERIALEMISSIVE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATEMISSIVE }, - { GE_CMD_MATERIALAMBIENT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATAMBIENTALPHA }, - { GE_CMD_MATERIALSPECULAR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - { GE_CMD_MATERIALSPECULARCOEF, FLAG_FLUSHBEFOREONCHANGE, DIRTY_MATSPECULAR }, - - // Light parameters - { GE_CMD_LX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LDX0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDY0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDZ0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDX1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDY1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDZ1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDX2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDY2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDZ2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDX3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDY3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDZ3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKA0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKB0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKA1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKB1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKA2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKB2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKA3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LKB3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LKC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKS0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKS1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKS2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKS3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LKO0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LKO1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LKO2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LKO3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - { GE_CMD_LAC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LDC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LSC0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT0 }, - { GE_CMD_LAC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LDC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LSC1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT1 }, - { GE_CMD_LAC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LDC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LSC2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT2 }, - { GE_CMD_LAC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LDC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - { GE_CMD_LSC3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_LIGHT3 }, - - // Ignored commands - { GE_CMD_TEXFLUSH, 0 }, - { GE_CMD_TEXLODSLOPE, 0 }, - { GE_CMD_TEXSYNC, 0 }, - - // These are just nop or part of other later commands. - { GE_CMD_NOP, 0 }, - { GE_CMD_BASE, 0 }, - { GE_CMD_TRANSFERSRC, 0 }, - { GE_CMD_TRANSFERSRCW, 0 }, - { GE_CMD_TRANSFERDST, 0 }, - { GE_CMD_TRANSFERDSTW, 0 }, - { GE_CMD_TRANSFERSRCPOS, 0 }, - { GE_CMD_TRANSFERDSTPOS, 0 }, - { GE_CMD_TRANSFERSIZE, 0 }, - - // From Common. No flushing but definitely need execute. - { GE_CMD_OFFSETADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_OffsetAddr }, - { GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_Origin }, // Really? - { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Prim }, - { GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Jump }, - { GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Call }, - { GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_Ret }, - { GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_End }, // Flush? - { GE_CMD_VADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Vaddr }, - { GE_CMD_IADDR, FLAG_EXECUTE, 0, &GPUCommon::Execute_Iaddr }, - { GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_BJump }, // EXECUTE - { GE_CMD_BOUNDINGBOX, FLAG_EXECUTE, 0, &GPUCommon::Execute_BoundingBox }, // + FLUSHBEFORE when we implement... or not, do we need to? // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_Vulkan::Execute_VertexType }, + { GE_CMD_PRIM, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Prim }, { GE_CMD_BEZIER, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Bezier }, { GE_CMD_SPLINE, FLAG_FLUSHBEFORE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_Spline }, - // These two are actually processed in CMD_END. - { GE_CMD_SIGNAL, FLAG_FLUSHBEFORE }, - { GE_CMD_FINISH, FLAG_FLUSHBEFORE }, - // Changes that trigger data copies. Only flushing on change for LOADCLUT must be a bit of a hack... { GE_CMD_LOADCLUT, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_LoadClut }, { GE_CMD_TRANSFERSTART, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC, 0, &GPUCommon::Execute_BlockTransferStart }, - - // We don't use the dither table. - { GE_CMD_DITH0 }, - { GE_CMD_DITH1 }, - { GE_CMD_DITH2 }, - { GE_CMD_DITH3 }, - - // These handle their own flushing. - { GE_CMD_WORLDMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_WorldMtxNum }, - { GE_CMD_WORLDMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_WorldMtxData }, - { GE_CMD_VIEWMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ViewMtxNum }, - { GE_CMD_VIEWMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ViewMtxData }, - { GE_CMD_PROJMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_ProjMtxNum }, - { GE_CMD_PROJMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_ProjMtxData }, - { GE_CMD_TGENMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPUCommon::Execute_TgenMtxNum }, - { GE_CMD_TGENMATRIXDATA, FLAG_EXECUTE, 0, &GPUCommon::Execute_TgenMtxData }, - { GE_CMD_BONEMATRIXNUMBER, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, 0, &GPU_Vulkan::Execute_BoneMtxNum }, - { GE_CMD_BONEMATRIXDATA, FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_BoneMtxData }, - - // Vertex Screen/Texture/Color - { GE_CMD_VSCX, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCY, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCZ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCS, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCT, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VTCQ, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VAP, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VFC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_VSCV, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - - // "Missing" commands (gaps in the sequence) - { GE_CMD_UNKNOWN_03, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_0D, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_11, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_29, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_34, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_35, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_39, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_4E, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_4F, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_52, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_59, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_5A, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_B6, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_B7, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_D1, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_ED, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_EF, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FA, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FB, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FC, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FD, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - { GE_CMD_UNKNOWN_FE, FLAG_EXECUTE, 0, &GPUCommon::Execute_Unknown }, - // Appears to be debugging related or something? Hit a lot in GoW. - { GE_CMD_UNKNOWN_FF, 0 }, }; GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) @@ -423,9 +109,24 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) ERROR_LOG(G3D, "gstate has drifted out of sync!"); } - // Sanity check cmdInfo_ table - no dupes please - std::set dupeCheck; memset(cmdInfo_, 0, sizeof(cmdInfo_)); + + // Import both the global and local command tables, and check for dupes + std::set dupeCheck; + for (size_t i = 0; i < commonCommandTableSize; i++) { + const u8 cmd = commonCommandTable[i].cmd; + if (dupeCheck.find(cmd) != dupeCheck.end()) { + ERROR_LOG(G3D, "Command table Dupe: %02x (%i)", (int)cmd, (int)cmd); + } else { + dupeCheck.insert(cmd); + } + cmdInfo_[cmd].flags |= (uint64_t)commonCommandTable[i].flags | (commonCommandTable[i].dirty << 8); + cmdInfo_[cmd].func = commonCommandTable[i].func; + if ((cmdInfo_[cmd].flags & (FLAG_EXECUTE | FLAG_EXECUTEONCHANGE)) && !cmdInfo_[cmd].func) { + Crash(); + } + } + for (size_t i = 0; i < ARRAY_SIZE(commandTable); i++) { const u8 cmd = commandTable[i].cmd; if (dupeCheck.find(cmd) != dupeCheck.end()) {