Line 14: |
Line 14: |
| | | |
| This ioctl takes an array of gpfifo entries where each entry points to a FIFO command list. This list is composed of alternating 32-bit words containing FIFO commands and their respective arguments. | | This ioctl takes an array of gpfifo entries where each entry points to a FIFO command list. This list is composed of alternating 32-bit words containing FIFO commands and their respective arguments. |
| + | |
| + | See the [[GPU|GPU]] page for a list of commands, with the register addresses and their descriptions. |
| | | |
| === Command Structure === | | === Command Structure === |
Line 75: |
Line 77: |
| |} | | |} |
| | | |
− | === Command List === | + | === SetObject === |
− | | |
− | All methods with values < 0x100 are special and executed by the PFIFO's DMA puller. The others are forwarded to the engine object currently bound to a given subchannel.
| |
− | | |
− | {| class="wikitable" border="1"
| |
− | |-
| |
− | ! Command || Method || Subchannel || Arg Count || Mode || Name
| |
− | |-
| |
− | | 0x2001?000 || 0x0000 || Variable || 1 || 1 || [[#BindObject|BindObject]]
| |
− | |-
| |
− | | 0x80000040 || 0x40 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0xA???0045 || 0x45 || 0 || Variable || 5 || SetGraphMacroCode
| |
− | |-
| |
− | | 0x20020047 || 0x47 || 0 || 2 || 1 || SetGraphMacroEntry
| |
− | |-
| |
− | | 0x800?0049 || 0x49 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x20056080 || 0x80 || 3 || Variable || 1 || ?
| |
− | |-
| |
− | | 0x20016085 || 0x85 || 3 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x20026086 || 0x86 || 3 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x20026088 || 0x88 || 3 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x2004608C || 0x8C || 3 || Variable || 1 || ?
| |
− | |-
| |
− | | 0x20016091 || 0x91 || 3 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x20026092 || 0x92 || 3 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x20026094 || 0x94 || 3 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x800160B5 || 0xB5 || 3 || 1 || 4 || ?
| |
− | |-
| |
− | | 0x800000BA || 0xBA || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x601000BE || 0xBE || 0 || 16 || 3 || ?
| |
− | |-
| |
− | | 0x200100BF || 0xBF || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200180C0 || 0xC0 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200400C9 || 0xC9 || 0 || 4 || 1 || SetOuterTessellationLevels
| |
− | |-
| |
− | | 0x200200CD || 0xCD || 0 || 2 || 1 || SetInnerTessellationLevels
| |
− | |-
| |
− | | 0x200100DC || 0xDC || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x800?00DF || 0xDF || 0 || Variable || 4 || SetRasterizerDiscard?
| |
− | |-
| |
− | | 0x20048100 || 0x100 || 4 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20028102 || 0x102 || 4 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x20018104 || 0x104 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x20018105 || 0x105 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x20018106 || 0x106 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C0 || 0x1C0 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C2 || 0x1C2 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C3 || 0x1C3 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200281C4 || 0x1C4 || 4 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x200181C5 || 0x1C5 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C6 || 0x1C6 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C7 || 0x1C7 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181C8 || 0x1C8 || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181CA || 0x1CA || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181CB || 0x1CB || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181CC || 0x1CC || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181CD || 0x1CD || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200181CF || 0x1CF || 4 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x800001D1 || 0x1D1 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x200301F0 || 0x1F0 || 0 || 3 || 1 || ?
| |
− | |-
| |
− | | 0x800001F3 || 0x1F3 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x200201F8 || 0x1F8 || 0 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x200401FA || 0x1FA || 0 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20016223 || 0x223 || 3 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x2004622C || 0x22C || 3 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20046230 || 0x230 || 3 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20046234 || 0x234 || 3 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x200203?? || 0x3?? Variable || 0 || 2 || 1 || SetScissors?
| |
− | |-
| |
− | | 0x20040360 || 0x360 || 0 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20010364 || 0x364 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x800?0368 || 0x368 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?036B || 0x36B || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?036C || 0x36C || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x2001036F || 0x36F || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x80000370 || 0x370 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000371 || 0x371 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000372 || 0x372 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x8???0373 || 0x373 || 0 || Variable || 4 || SetPatchSize
| |
− | |-
| |
− | | 0x80000374 || 0x374 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x20010376 || 0x376 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x800?03D5 || 0x3D5 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?03D6 || 0x3D6 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?03D7 || 0x3D7 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x200103D9 || 0x3D9 || 0 || 1 || 1 || SetTiledCacheTileSize
| |
− | |-
| |
− | | 0x80?003DE || 0x3DE || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800003E0 || 0x3E0 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x200203E7 || 0x3E7 || 0 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x800003ED || 0x3ED || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800203EE || 0x3EE || 0 || 2 || 4 || ?
| |
− | |-
| |
− | | 0x200403EF || 0x3EF || 0 || 4 || 1 || SetSampleMask
| |
− | |-
| |
− | | 0x800003F5 || 0x3F5 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800103F6 || 0x3F6 || 0 || 1 || 4 || ?
| |
− | |-
| |
− | | 0x200503F8 || 0x3F8 || 0 || 5 || 1 || ?
| |
− | |-
| |
− | | 0x200203FD || 0x3FD || 0 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x2004040C || 0x40C || 0 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x200C0420 || 0x420 || 0 || 12 || 1 || ?
| |
− | |-
| |
− | | 0x80000446 || 0x446 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000451 || 0x451 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800?0452 || 0x452 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x20100458 || 0x458 || 0 || 16 || 1 || ?
| |
− | |-
| |
− | | 0x20040478 || 0x478 || 0 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x8000047C || 0x47C || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x8000047E || 0x47E || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x8001047F || 0x47F || 0 || 1 || 4 || ResolveDepthBuffer
| |
− | |-
| |
− | | 0x2003048A || 0x48A || 0 || 3 || 1 || ?
| |
− | |-
| |
− | | 0x800?04B3 || 0x4B3 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800104B9 || 0x4B9 || 0 || 1 || 4 || ?
| |
− | |-
| |
− | | 0x800?04BA || 0x4BA || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800004BB || 0x4BB || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800?04C3 || 0x4C3 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x200104C4 || 0x4C4 || 0 || 1 || 1 || SetAlphaRef
| |
− | |-
| |
− | | 0x200404C7 || 0x4C7 || 0 || 4 || 1 || SetBlendColor
| |
− | |-
| |
− | | 0x800004E0 || 0x4E0 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800?04E5 || 0x4E5 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?04E6 || 0x4E6 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x800?04E7 || 0x4E7 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x200204EC || 0x4EC || 0 || 2 || 1 || SetLineWidth
| |
− | |-
| |
− | | 0x800?050D || 0x50D || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80000519 || 0x519 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000540 || 0x540 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x20010546 || 0x546 || 0 || 1 || 1 || SetPointSize
| |
− | |-
| |
− | | 0x2001054C || 0x54C || 0 || 1 || 1 || ResetCounter
| |
− | |-
| |
− | | 0x800?054E || 0x54E || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x20030554 || 0x554 || 0 || 3 || 1 || SetRenderEnableConditional
| |
− | |-
| |
− | | 0x800?0556 || 0x556 || 0 || Variable || 4 || SetRenderEnable?
| |
− | |-
| |
− | | 0x2001055B || 0x55B || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x2001056F || 0x56F || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x80000572 || 0x572 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800?0574 || 0x574 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x8000057F || 0x57F || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000580 || 0x580 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000591 || 0x591 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x20010592 || 0x592 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200205F2 || 0x5F2 || 0 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x800?05F6 || 0x5F6 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x2001061F || 0x61F || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x800?0620 || 0x620 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80010646 || 0x646 || 0 || 1 || 4 || ?
| |
− | |-
| |
− | | 0x800?0648 || 0x648 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x2001064F || 0x64F || 0 || 1 || 1 || SetDepthClamp
| |
− | |-
| |
− | | 0x800?066F || 0x66F || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x120020671 || 0x671 || 0 || 2 || 9 || ?
| |
− | |-
| |
− | | 0x20010674 || 0x674 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x8000068B || 0x68B || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x200406C0 || 0x6C0 || 0 || 4 || 1 || ?
| |
− | |-
| |
− | | 0x20010703 || 0x703 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x200207?? || 0x7?? Variable || 0 || 2 || 1 || ?
| |
− | |-
| |
− | | 0x80300830 || 0x830 || 0 || 48 || 4 || ?
| |
− | |-
| |
− | | 0x80400840 || 0x840 || 0 || 64 || 4 || ?
| |
− | |-
| |
− | | 0x80500850 || 0x850 || 0 || 80 || 4 || ?
| |
− | |-
| |
− | | 0x200308E0 || 0x8E0 || 0 || 3 || 1 || ?
| |
− | |-
| |
− | | 0x200308E3 || 0x8E3 || 0 || 3 || 1 || CB_POS(Const buffer position)
| |
− | |-
| |
− | | 0x200308E4 || 0x8E4 || 0 || 3 || 1 || ?
| |
− | |-
| |
− | | 0x80??0904 || 0x904 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80??090C || 0x90C || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80??0914 || 0x914 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80??091C || 0x91C || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80??0924 || 0x924 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x80000D1E || 0xD1E || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x800?0D28 || 0xD28 || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x20010D29 || 0xD29 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x20010D34 || 0xD34 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0xA0020E00 || 0xE00 || 0 || 2 || 5 || BeginTransformFeedback
| |
− | |-
| |
− | | 0x20010E02 || 0xE02 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0x80020E04 || 0xE04 || 0 || 2 || 4 || ?
| |
− | |-
| |
− | | 0x20010E06 || 0xE06 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0xA0030E0A || 0xE0A || 0 || 3 || 5 || ?
| |
− | |-
| |
− | | 0x80050E0C || 0xE0C || 0 || 5 || 4 || ?
| |
− | |-
| |
− | | 0x800?0E0E || 0xE0E || 0 || Variable || 4 || ?
| |
− | |-
| |
− | | 0x20010E10 || 0xE10 || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0xA0040E12 || 0xE12 || 0 || 4 || 5 || ?
| |
− | |-
| |
− | | 0x20010E1A || 0xE1A || 0 || 1 || 1 || ?
| |
− | |-
| |
− | | 0xA0040E1C || 0xE1C || 0 || 4 || 5 || ?
| |
− | |-
| |
− | | 0x81900E1E || 0xE1E || 0 || 400 || 4 || ?
| |
− | |-
| |
− | | 0x80000E20 || 0xE20 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0x80000E24 || 0xE24 || 0 || 0 || 4 || ?
| |
− | |-
| |
− | | 0xA0040E2C || 0xE2C || 0 || 4 || 5 || PushDebugGroup
| |
− | |-
| |
− | | 0xA0020E2E || 0xE2E || 0 || 2 || 5 || PopDebugGroupId
| |
− | |-
| |
− | | 0xA0030E30 || 0xE30 || 0 || 3 || 5 || DrawArrays
| |
− | |-
| |
− | | 0xA0050E32 || 0xE32 || 0 || 5 || 5 || DrawArraysIndirect?
| |
− | |-
| |
− | | 0xA0050E34 || 0xE34 || 0 || 5 || 5 || DrawArraysInstanced?
| |
− | |-
| |
− | | 0xA0050E36 || 0xE36 || 0 || 5 || 5 || DrawElements
| |
− | |-
| |
− | | 0xA0060E38 || 0xE38 || 0 || 6 || 5 || DrawElementsIndirect?
| |
− | |-
| |
− | | 0xA0060E3A || 0xE3A || 0 || 6 || 5 || DrawElementsInstanced?
| |
− | |-
| |
− | | 0xA0050E42 || 0xE42 || 0 || 5 || 5 || ?
| |
− | |-
| |
− | | 0xA0060E44 || 0xE44 || 0 || 6 || 5 || ?
| |
− | |}
| |
− | | |
− | Note: These still need to be heavily verified and ''could'' be wrong.
| |
− | | |
− | === BindObject ===
| |
| | | |
− | In order to bind an engine object to a specific subchannel, method 0 (BindObject) must be used first. The target subchannel is specified in bits 15-13 of the command word. | + | In order to bind an engine object to a specific subchannel, method 0 (SetObject) must be used first. The target subchannel is specified in bits 15-13 of the command word. |
| | | |
| After the engine object is bound to the desired subchannel, setting it's value in bits 15-13 of any subsequent command word will make PFIFO forward the command to the target engine. | | After the engine object is bound to the desired subchannel, setting it's value in bits 15-13 of any subsequent command word will make PFIFO forward the command to the target engine. |
| | | |
− | This method only takes one argument, an [[#Engine_IDs|engine ID]]. | + | This method only takes one argument, an [[#Engine_IDs|Engine ID]]. |
| | | |
| ==== Engine IDs ==== | | ==== Engine IDs ==== |
Line 465: |
Line 120: |
| Command lists can contain fences to ensure that commands are executed on the correct order, and subsequent commands are only sent when the previously sent commands were already processed by the GPU. Fences uses the QUERY_* commands, and works like this: | | Command lists can contain fences to ensure that commands are executed on the correct order, and subsequent commands are only sent when the previously sent commands were already processed by the GPU. Fences uses the QUERY_* commands, and works like this: |
| | | |
− | * First, QUERY_ADDRESS_HIGH and QUERY_ADDRESS_LOW commands are added to the Command List, with the High/Low 32 bits part of the 64-bits GPU Virtual Address where the fence is located. This GPU Virtual Address needs to be mapped to the process Virtual Address beforehand. | + | * First, register ReportSemaphoreOffset is set to High/Low 32 bits part of the 64-bits GPU Virtual Address where the fence is located. This GPU Virtual Address needs to be mapped to the process Virtual Address beforehand. |
− | * Then, QUERY_SEQUENCE is added with a sequential number. This number is basically a incrementing counter, so the first Command List can have QUERY_SEQUENCE = 1, the next one QUERY_SEQUENCE = 2, 3, 4... and so on. | + | * Then, ReportSemaphorePayload is set with a sequential number. This number is basically a incrementing counter, so the first Command List can set ReportSemaphorePayload = 1, the next one to 2, then 3, 4... and so on. |
− | * Finally, QUERY_GET is added and contains the mode and other unknown data. | + | * Finally, ReportSemaphoreControl is added and contains the mode and other unknown data. |
− | | |
− | The above commands are added using the [[#Submission_mode|increasing mode]], since the Ids for all those 4 registers are sequential.
| |
− | | |
− | ==== QUERY_GET Structure ====
| |
− | | |
− | {| class="wikitable"
| |
− | |-
| |
− | ! scope="col"| Bits
| |
− | ! scope="col"| Description
| |
− | |-
| |
− | |1-0
| |
− | |Mode
| |
− | |-
| |
− | |4
| |
− | |Fence
| |
− | |-
| |
− | |15-12
| |
− | |Unit
| |
− | |}
| |
− | | |
− | ==== QUERY_GET Mode ====
| |
− | | |
− | {| class="wikitable"
| |
− | |-
| |
− | ! scope="col"| Value
| |
− | ! scope="col"| Mode
| |
− | |-
| |
− | |0
| |
− | |Write
| |
− | |-
| |
− | |1
| |
− | |Sync
| |
− | |-
| |
− | |2
| |
− | |Write ?
| |
− | |-
| |
− | |3
| |
− | |Write ?
| |
− | |}
| |
− | | |
− | TODO: Move this to a separate page with all GPU Commands with descriptions. Also figure out what the other values mean.
| |
| | | |
− | Some of the other fields are still unknown/unobserved.
| + | The above commands are added using the [[#Submission_mode|increasing mode]], since all those 4 registers are sequential. |
| | | |
− | Official games will set Mode to 0, Fence to 1 and Unit to 0xF. The QUERY_SEQUENCE value is then written by the GPU to the address pointed to by QUERY_ADDRESS. | + | Official games will sets Operation to 0 (Release), bit 4 to 1, bits 15-12 (Unit) to 0xF, and bit 28 to 1 (OneWord). The ReportSemaphorePayload value is then written by the GPU to the address pointed to by ReportSemaphoreOffset. |
− | On the CPU side, the game code should wait until the value at the address pointed to by QUERY_ADDRESS is >= to the last written SEQUENCE value. Official code waits for this condition to be true on a loop, and won't send any further commands before that. | + | On the CPU side, the game code should wait until the value at the address pointed to by ReportSemaphoreOffset is >= to the last written value. Official code waits for this condition to be true on a loop, and won't send any further commands before that. |
| | | |
| == Vertex Data Submission == | | == Vertex Data Submission == |