Difference between revisions of "GPU/Shader Instruction Set"

From 3dbrew
< GPU
Jump to navigation Jump to search
m
Line 4: Line 4:
 
A compiled shader binary is comprised of two parts : the main instruction sequence and the operand descriptor table. These are both sent to the GPU around the same time but using separate [[GPU Commands]]. Instructions (such as format 1 instruction) may reference operand descriptors. When such is the case, the operand descriptor ID is the offset, in words, of the descriptor within the table.
 
A compiled shader binary is comprised of two parts : the main instruction sequence and the operand descriptor table. These are both sent to the GPU around the same time but using separate [[GPU Commands]]. Instructions (such as format 1 instruction) may reference operand descriptors. When such is the case, the operand descriptor ID is the offset, in words, of the descriptor within the table.
 
Both instructions and descriptors are coded in little endian.
 
Both instructions and descriptors are coded in little endian.
[https://github.com/smealum/aemstro] includes a basic implementation of the following specification.
+
A basic implementation of the following specification can be found at [https://github.com/smealum/aemstro]
  
 
== Instruction formats ==
 
== Instruction formats ==

Revision as of 19:22, 26 February 2014


Overview

A compiled shader binary is comprised of two parts : the main instruction sequence and the operand descriptor table. These are both sent to the GPU around the same time but using separate GPU Commands. Instructions (such as format 1 instruction) may reference operand descriptors. When such is the case, the operand descriptor ID is the offset, in words, of the descriptor within the table. Both instructions and descriptors are coded in little endian. A basic implementation of the following specification can be found at [1]

Instruction formats

Format 1 : (used for register instructions)

Offset Size Description
0x0 0x6 Operand descriptor ID (DESC)
0x6 0x6 Source 1 register (SRC2)
0xC 0x6 Source 2 register (SRC1)
0x12 0x2 Flags
0x24 0x2 Destination register (DST)
0x1A 0x6 Opcode

Format 2 : (used for flow control instructions)

Offset Size Description
0x0 0x8 Number of instructions ? (NUM)
0x8 0x10? Destination offset (DST)
0x1A 0x6 Opcode

Instructions

Opcode Format Name Description
0x01 1 DP3 Computes dot product on 3-component vectors; DST = SRC1.SRC2
0x02 1 DP4 Computes dot product on 4-component vectors; DST = SRC1.SRC2
0x13 1 MOV Moves value from one register to another; DST = SRC1
0x24 2 CALL Jumps to DST and executes NUM instructions
0x21 1 END2 ?
0x22 1 END1 ?

Operand descriptors

Offset Size Description
0x0 0x4 Destination component mask. Bit 3 = x, 2 = y, 1 = z, 0 = w.
0x5 0x8 Source 1 component selector
0x14 0x8 Source 2 component selector
0x1F 0x1 Flag

Component selector :

Offset Size Description
0x0 0x2 Component 3 value
0x2 0x2 Component 2 value
0x4 0x2 Component 1 value
0x6 0x2 Component 0 value
Value Component
0x0 x
0x1 y
0x2 z
0x3 w

The component selector enables swizzling. For example, component selector 0x1B is equivalent to .xyzw, while 0x55 is equivalent to .yyyy.

Registers

It is not yet fully understood how registers are organized. It does however seem that registers are separated into various banks, some RO, some WO and some RW. Because of this separation, a given register ID may not refer to the same register value when it is used as SRC or as DST. Since the PICA200 does not support fragment shaders, WO registers are fixed function.

RO registers :

Register ID Description
0x0 vertex.position
0x1 vertex.texcoord ?
0x4 vertex.color ?
0x6 vertex.color ?

WO registers :

Register ID Description
0x0 result.position
0x2 result.texcoord ?
0x4 result.color ?
0x6 result.texcoord ?

(these are mostly guesses aside from vertex.position and result.position)

Registers within the 0x20-0x40 ranges seem to be RW. They are often used to access matrix data.