PS3:HvReverseEngineering:RSXFIFOCommands
From wikibrew
Crossreference: ps3devwiki::RSXFIFOCommands
Commands
NOP (0x00000100)
- Nop
0x00000100
CALL (0x00000002)
- Calls a function at the specified offset.
- Command size is 0.
- The parameter is offset in FIFO buffer.
<offset> | 0x00000002
RET (0x00020000)
- Returns from a function.
- Command size is 0.
0x00020000
JMP (0x20000000)
- Jumps to the specified offset.
- Command size is 0.
- The parameter is offset in FIFO buffer.
0x20000000 | <offset>
COLOR MASK (0x00040324)
- Sets color mask.
- Command size is 1.
- The parameter is color mask.
0x00040324 <color mask>
COLOR MASK MRT (0x00040370)
0x00040370 <color mask>
CLEAR COLOR (0x00041D90)
0x00041D90 <value>
FRONT POLYGON MODE (0x00041828)
- Sets front polygon mode.
- Command size is 1.
- The parameter is front polygon mode.
0x00041828 <front polygon mode>
SET REF (0x00040050)
- Sets value of REF control register
0x00040050 <value>
SEMAPHORE DMA CONTEXT (0x00040060)
- Sets semaphore DMA context
0x00040060 <value>
SEMAPHORE OFFSET (0x00040064)
- Sets semaphore offset
0x00040064 <value>
SEMAPHORE ACQUIRE (0x00040068)
- Acquires semaphore
0x00040068 <value>
SEMAPHORE RELEASE (0x0004006C)
- Releases semaphore
0x0004006C <value>
libgcm Functions
cellGcmGetControlRegister
- Returns EA of FIFO registers: PUT, GET and REF
cellGcmFlush
- Kicks FIFO command processing by moving PUT register
cellGcmFinish
- This function adds FIFO command for setting REF register to value 0xFFFFFFFF, kicks FIFO and then loops and checks REF register until it is set to value 0xFFFFFFFF.
- It just waits until all FIFO commands are processed by GPU.
cellGcmGetFlipStatus
- Returns flip status.
- Checks bit 31 in word at offset 0x10C0 + 0x1 * 0x40 of reports area returned by lv1_gpu_context_allocate.
- Flip status = ((word at 0x10C0 + 0x1 * 0x40) >> 31) ^ 0x1.
- Flip status: 0 - flip done, 1 - flip waiting
cellGcmResetFlipStatus
- Resets flip status.
- Sets flip status to flip waiting.
- Sets bit 31 to 0 in word at offset 0x10C0 + 0x1 * 0x40 of reports area returned by lv1_gpu_context_allocate.
Equivalent to:
lv1_gpu_context_attribute(context handle, 0x10a, 0x1 /* id */, 0x7fffffff /* mask */, 0x0 /* value */, 0x0)
cellGcmSetWaitFlip
- Blocks RSX until flip is done
- Actually it's just semaphore acquire with offset 0x00000010 and value 0x00000000
- Uses internally cellGcmSetWaitLabel function.
cellGcmGetLastFlipTime
- Returns timestamp of last flip.
- Reads 8 bytes at offset 0x10B0 + 0x1 * 0x40 + 0x8 of reports area returned by lv1_gpu_context_allocate.
cellGcmGetVBlankCount
- Returns V-blank count.
- Reads 8 bytes at offset 0x10E0 + 0x1 * 0x40 + 0x8 of reports area returned by lv1_gpu_context_allocate.
cellGcmGetLastSecondVTime
- Reads 8 bytes at offset 0x1118 of reports area returned by lv1_gpu_context_allocate.
libgcm Commands
SetNopCommand
0x00000000
SetReferenceCommand
0x00040050 <param>
SetJumpCommand
0x20000000 | <param>
SetCallCommand
0x00000002 | <param>
SetReturnCommand
0x00002000
SetLogicOp
- Sets pixel logical operation
0x00040378 <param>
SetLogicOpEnable
- Enables/Disables pixel logical operation
0x00040374 <param>
SetColorMask
0x00040324 <param>
SetColorMaskMrt
0x00040370 <param>
SetClearColor
0x00041D90 <param>
SetClearDepthStencil
0x00041D8C <param>
SetClearSurface
- Clears buffers
0x00041D94 <mask> # 0x00000001 - Z buffer, 0x000000f0 - color buffer 0x00040100 0x00000000
SetFrontPolygonMode
0x00041828 <param>
SetFrontFace
0x00041834 <param>
SetAlphaTestEnable
0x00040304 <param>
SetAlphaFunc
0x00080308 <param1> <param2>
SetDepthTestEnable
0x00040A74 <param>
SetDepthFunc
0x00040A6C <param>
SetDepthBounds
0x00080384 <param1> <param2>
SetBlendEnable
0x00040310 <param>
SetBlendFunc
0x00080314 <param1> <param2>
SetBlendColor
0x0004031C <param> 0x0004037C <param>
SetBlendEquation
0x00040320 <param>
SetClipMinMax
- Sets Z clipping values
0x00080394 <param1> <param2>
SetZcullEnable
- Enables/Disables Zcull/Scull
0x00041D84 <param>
SetPointSize
0x00041EE0 <param>
SetScissor
0x000808C0 <width << 16 | x> <height << 16 | y>
SetAntiAliasingControl
0x00041D7C <param>
SetWriteCommandLabel
- Releases semaphore.
0x00040064 <param> 0x0004006C <param>
SetWaitLabel
- Acquires semaphore.
0x00040064 <param> 0x00040068 <param>
SetWriteBackEndLabel
0x00041D6C <label index << 4> 0x00041D70 <(label value & 0xFF00FF00) | ((label value & 0xFF) << 16) | ((label value >> 16) & 0xFF)>
SetWriteBackEndLabelForConditional
0x00041D6C <param> 0x00041D70 <param> 0x00040110 0x00000000
SetWaitForIdle
0x00040110 0x00000000
SetWaitFlip
- SetWaitFlip is nothing more than acquiring semaphore.
- This command is equal to SetWaitLabel with index=0x00000001 and value=0x00000000.
0x00040064 0x00000010 # semaphore offset = index * 16 0x00040068 0x00000000
SetFlipCommand
0x0004E944 <buffer id> 0x00040060 0x56616661 0x00040064 0x00000030 0x0004006C 0x00000000 0x00040064 0x00000030 0x00040068 0x00000001 0x00000002 0x00040064 0x00000010 0x0004006C 0xFFFFFFFF 0x0004E924 0x8000010F
SetFlipCommandWithWaitLabel
0x0004E944 <buffer id> 0x00040060 0x56616661 0x00040064 0x00000030 0x0004006C 0x00000000 0x00040064 0x00000030 0x00040068 0x00000001 0x00000002 0x00040064 <semaphore offset> 0x00040068 <semaphore value> 0x00040064 0x00000010 0x0004006C 0xFFFFFFFF 0x0004E924 0x8000010F
SetReportLocation
0x000401A8 <param>
SetReport
0x00041800 <param>
SetTimeStamp
0x00041800 <param>
SetClearReport
0x000417c8 <param>
SetFrontFace
0x00041834 <param> # 0x900 - cw, 0x901 - ccw
SetCullFace
- Specifies culling face (front or back)
0x00041830 <param>
SetCullFaceEnable
- Enables/Disables face culling
0x0004183C <param>
SetViewport
0x00080A00 <width << 16 | x> <height << 16 | y> 0x00080394 <min> <max> 0x00200A20 <offset 0> <offset 1> <offset 2> <offset 3> <scale 0> <scale 1> <scale 2> <scale 3> 0x00200A20 <offset 0> <offset 1> <offset 2> <offset 3> <scale 0> <scale 1> <scale 2> <scale 3>
SetLineWidth
0x000403B8 <param>
SetLineSmoothEnable
0x000403BC <param>
SetShadeMode
0x00040368 <mode> # flat - 0x1D00, smooth - 0x1D01
SetTextureAddress
0x00041A08 + (param1 << 5) <param2>
SetTextureControl
0x00041A0C + (param1 << 5) <param2>
SetTextureFilter
0x00041A14 + (param1 << 5) <param2>
SetFogMode
0x000408CC <param>
SetNotifyIndex
0x00040180 0x6660420F - <param>
SetNotify
0x00040104 0x00000000 0x00040100 0x00000000
SetTransferDataMode
0x00082184 <source> # 0xFEED0000 - local memory, 0xFEED0001 - system memory <destination> # 0xFEED0000 - local memory, 0xFEED0001 - system memory
SetTransferDataOffset
0x0004230C <source address> 0x00042310 <destination address> 0x00042328 0x00000000
SetTransferDataFormat
0x00142314 <source pitch> <destination pitch> <line length> <line count> <destination increment> << 8 | <source increment>
SetTransferLocation
0x00046188 <destination> # 0xFEED0000 - local memory, 0xFEED0001 - system memory
SetTransferData
- Uses DMA controller of RSX to transfer data
0x00082184
<source> # 0xFEED0000 - local memory, 0xFEED0001 - system memory
<destination> # 0xFEED0000 - local memory, 0xFEED0001 - system memory
for (each row)
{
0x0020230C
<source address>
<destination address>
0x00000000
0x00000000
<number of bytes to transfer> # max 0x3FFFFF bytes
0x00000001
0x00000101
0x00000000
}
SetInlineTransfer
- Transfers data from FIFO command buffer to VRAM or GART memory
- Use SetTransferLocation to set the destination memory
0x0004630C
<destination address> & ~0x3F
0x00086300
0x0000000B
0x10001000
0x000CA304
(<destination address> >> 2) & 0xF
0x00010000 | <size in words>
0x00010000 | <size in words>
(((size in words + 1) & ~0x1) << 18) | 0x0000A400
for (each word)
{
<word>
}
if (size in words & 0x1)
0x00000000
SetTransferImage
0x00046188 <destination> # 0xFEED0000 - video ram, 0xFEED0001 - gart ram 0x0004C184 <source> # 0xFEED0000 - video ram, 0xFEED0001 - gart ram 0x0004C198 0x313371C3 0x0004630C <dst offset + (x & ~0x3FF) * bytes per pixel + (y & ~0x3FF) * dst pitch> 0x00086300 <bytes per pixel> # 0xA - 4 bytes, 0x4 - 2 bytes <dst pitch << 16 | dst pitch> 0x0024C2FC 0x00000001 <bytes per pixel> # 0x3 - 4 bytes, 0x7 - 2 bytes 0x00000003 <(y & 0x3FF) << 16 | x & 0x3FF> <block height << 16 | block width> <(y & 0x3FF) << 16 | x & 0x3FF> <block height << 16 | block width> 0x00100000 0x00100000 0x0010C400 <block height << 16 | 0x10 or (block width + 1) & ~0x1> <0x00020000 | src pitch> <src offset + (src x + x - dst x) * bytes per pixel + (src y + y - dst y) * src pitch> 0x00000000
SetSurfaceWindow
0x00040194 <color location 0> # 0xFEED0000 - video ram, 0xFEED0001 - gart ram 0x0004018C <color location 1> 0x000801B4 <color location 2> <color location 3> 0x00040198 <depth location> 0x00180208 <log2(height) << 24 | log2(width) << 16 | antialias << 12 | type << 8 | depthFormat << 5 | color format> <color pitch 0> <color offset 0> <depth offset> <color offset 1> <color pitch 1> 0x0004022C <depth pitch> 0x00100280 <color pitch 2> <color pitch 3> <color offset 2> <color offset 3> 0x00040220 <color target> 0x000402B8 <y << 16 | x> 0x00080200 <width << 16 | x> <height << 16 | y> 0x00041D88 <pixel offset << 16 | origin << 12 | (height - (height >> 12) & 0x1)>
SetVertexTextureAddress
0x00040908 + (index * 0x20) (wrapt << 8) | wraps
SetVertexDataArrayFormat
0x00041740 + (vertex attribute index * 0x4) <frequency << 16 | stride << 8 | size << 4 | type>
SetVertexDataArrayOffset
0x00041680 + (vertex attribute index * 0x4) <location << 31 | offset> # location: 0 - video RAM, 1 - GART memory
SetVertexDataArray
0x00041740 + (vertex attribute index * 0x4) <frequency << 16 | stride << 8 | size << 4 | type> 0x00041680 + (vertex attribute index * 0x4) <location << 31 | offset> # location: 0 - video RAM, 1 - GART memory
SetVertexAttribInputMask
0x00041FF0 <mask>
SetVertexAttribOutputMask (SetFragmentAttribInputMask)
0x00041FF4 <mask>
SetVertexProgramConstants
- Sets value of constant registers in vertex shader, e.g. ModelViewProject matrix.
- RSX has 468 vertex constant registers.
- Every vertex constant register is of type float4x4.
- Used by SetVertexProgramParameter.
ptr = data
for (j = 0, index = start; j < count; j += 32, index += 8)
{
0x00841EFC
<index>
for (k = 0; k < 8; k++) # one vertex constant register is float4x4
{
<*ptr++>
<*ptr++>
<*ptr++>
<*ptr++>
}
}
if ((count & 0x1F) != 0)
{
<((count & 0x1F) + 1) << 18 | 0x1EFC>
<index>
for (; j < count; j++)
<*ptr++>
}
SetVertexData1f
0x00041E40 + (vertex attribute index * 0x4) <value>
SetVertexData2f
0x00081880 + (vertex attribute index * 0x8) <value1> <value2>
SetVertexData3f
0x000C1500 + (vertex attribute index * 0x10) <value1> <value2> <value3>
SetVertexData4f
0x00101C00 + (vertex attribute index * 0x10) <value1> <value2> <value3> <value4>
SetVertexData4s
0x00081980 + (vertex attribute index * 0x8) <value2 << 16 | value1> <value4 << 16 | value3>
SetVertexData4ub
0x00041940 + (vertex attribute index * 0x4) <value4 << 24 | value3 << 16 | value2 << 8 | value1>
SetDrawBegin
0x400C1714 0x00000000 0x00000000 0x00000000 0x00041808 <mode>
SetDrawEnd
0x00041808 0x00000000
SetDrawArrays
0x400C1714
0x00000000
0x00000000
0x00000000
0x00041808
<mode>
0x00041814;
<(((count - 1) & 0xff) << 24) | first>
first += ((count - 1) & 0xff) + 1
count -= ((count - 1) & 0xff) + 1
while (count >= (0x7ff * 0x100)) {
<(0x7ff << 18) | 0x40001814>
for (i = 0; i < 0x7ff; i++) {
<((0x100 - 1) << 24) | first>
first += 0x100;
}
count -= 0x7ff * 0x100;
}
if (count) {
<(count << 18) | 0x40001814>
for (i = 0; i < count; i++) {
<((0x100 - 1) << 24) | first>
first += 0x100;
}
}
0x00041808
0x00000000
SetVertexProgramRegisterCount
0x00041EF8
if (register count <= 32)
<0x0020FFFF>
else
<0x0030FFFF>
SetVertexProgramStartSlot
0x00041EA0 <start slot> # 0 - 511, RSX supports 512 instructions
SetVertexProgramLoadSlot
0x00041E9C
<start slot> # 0 - 511, RSX supports 512 instructions
for (each 32 instructions)
{
0x00800B80
<ucode word>
...
<ucode word>
}
if (istruction count & 0x7)
{
<0x00000B80 | (instruction count & 0x7) << 20>
<ucode word>
...
<ucode word>
}
SetFragmentProgramOffset
0x000408E4
<fragment program offset & 0x1FFFFFFF | (location + 1)> # location: 0 - video RAM, 1 - GART memory
0x00041FF4
<mask>
index = 0
while (texCoordsInputMask)
{
if (texCoordsInputMask & 0x1)
{
<0x00040B40 + index << 2>
<texCoords2D & 0x1 | (texCoordsCentroid & 0x1) << 4>
}
texCoordsInputMask >>= 1
texCoordsCentroid >>= 1
texCoords2D >>= 1
index++
}
SetFragmentProgramControl
# register count is at least 2
if (register count <= 1)
register count = 2
if (depth replace)
tmp = 0x7
else
tmp = 0x0
0x00041D60
<register count << 24 | (0x400 | (replace TXP with TEX << 15)) | (pixel kill << 7) | (!output_from_H0 << 6) | (tmp << 1)>
SetFragmentProgramGammaEnable
0x00041FEC <enable>
SetInvalidateTextureCache
0x00041FD8 <param>
System Semaphores
DMA Context 0x66616661
- These semaphores are located in video RAM returned by LV1 in lpar_reports.
| Offset | Value | Description |
|---|---|---|
| 0x00000000 | 0x00000000 | Flip HEAD 0 done(used e.g. by cellGcmWaitFlip). LV1 sets this semaphore to value 0x0 after a flip of head 0 occurred. |
| 0x00000010 | 0x00000000 | Flip HEAD 1 done(used e.g. by cellGcmWaitFlip). LV1 sets this semaphore to value 0x0 after a flip of head 1 occurred. |
DMA Context 0x56616661
- These semaphores are located in video RAM returned by LV1 in lv1_gpu_device_map(8).
Semaphores
Small Test
Here is a FIFO program i executed on Linux:
0x00040060 # set semaphore DMA context method 0x66616661 # DMA object handle 0x00040064 # set semaphore offset method 0x00000400 # semaphore offset 0x0004006C # semaphore release method 0xf00dbeef # semaphore value
And here is dump of reports area:
000003f8: 0x1337beef 000003fc: 0x1337f001 00000400: 0xf00dbeef # semaphore value 00000404: 0x1337babe 00000408: 0x1337beef 0000040c: 0x1337f001
- As you see releasing semaphore writes 0xf00dbeef to reports area at offset 0x400.