Hi,

while I've had less success (read: hard locks and reboots) with the recently 
drmtest and r300_demo, I did use glxtest to find out registers of the R300.

Basically, what I did is run a small GL program, get the command buffer, 
make some small changes and rerun. Often, this results in only a small 
change in the command buffer (found using diff), which makes it possible to 
guess register addresses and constants. So while I haven't been able to 
crosstest my results by _sending_ commands using my new knowledge, I am 
pretty certain that they are mostly correct (as long as there is no 
explicit comment stating otherwise).

So far, I have found registers for alpha blending and testing among other 
things. I have also decoded most of the vertex program instruction set. 
However, I do not have the registers for vertex program *setup* yet. All I 
know is that both the program and its environment/parameters (whatever you 
want to call it) are uploaded via 0x2208.

All my findings are documented in the attached header file.

cu,
Nicolai
// The entire range from 0x2300 to 0x2AC inclusive seems to be used for
// immediate vertices
#define R300_VAP_VTX_COLOR_R                0x2464
#define R300_VAP_VTX_COLOR_G                0x2468
#define R300_VAP_VTX_COLOR_B                0x246C
#define R300_VAP_VTX_POS_0_X_1              0x2490 // used for glVertex2*()
#define R300_VAP_VTX_POS_0_Y_1              0x2494
#define R300_VAP_VTX_COLOR_PKD              0x249C // RGBA
#define R300_VAP_VTX_POS_0_X_2              0x24A0 // used for glVertex3*()
#define R300_VAP_VTX_POS_0_Y_2              0x24A4
#define R300_VAP_VTX_POS_0_Z_2              0x24A8
#define R300_VAP_VTX_END_OF_PKT             0x24AC // write 0 to indicate end of packet?

/* gap */
#define R300_PP_ALPHA_TEST                  0x4BD4
#       define R300_REF_ALPHA_MASK               0x000000ff
#       define R300_ALPHA_TEST_FAIL              (0 << 8)
#       define R300_ALPHA_TEST_LESS              (1 << 8)
#       define R300_ALPHA_TEST_LEQUAL            (2 << 8)
#       define R300_ALPHA_TEST_EQUAL             (3 << 8)
#       define R300_ALPHA_TEST_GEQUAL            (4 << 8)
#       define R300_ALPHA_TEST_GREATER           (5 << 8)
#       define R300_ALPHA_TEST_NEQUAL            (6 << 8)
#       define R300_ALPHA_TEST_PASS              (7 << 8)
#       define R300_ALPHA_TEST_OP_MASK           (7 << 8)
#       define R300_ALPHA_TEST_ENABLE            (1 << 11)
/* gap */

// Notes:
// - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in the application
// - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND are set to the same
//   function (both registers are always set up completely in any case)
// - Most blend flags are simply copied from R200 and not tested yet
#define R300_RB3D_CBLEND                    0x4E04
#define R300_RB3D_ABLEND                    0x4E08
 /* the following only appear in CBLEND */
#       define R300_BLEND_ENABLE                     (1 << 0)
#       define R300_BLEND_UNKNOWN                    (3 << 1)
#       define R300_BLEND_NO_SEPARATE                (1 << 3)
 /* the following are shared between CBLEND and ABLEND */
#       define R300_FCN_MASK                         (3  << 12)
#       define R300_COMB_FCN_ADD_CLAMP               (0  << 12)
#       define R300_COMB_FCN_ADD_NOCLAMP             (1  << 12)
#       define R300_COMB_FCN_SUB_CLAMP               (2  << 12)
#       define R300_COMB_FCN_SUB_NOCLAMP             (3  << 12)
#       define R300_SRC_BLEND_GL_ZERO                (32 << 16)
#       define R300_SRC_BLEND_GL_ONE                 (33 << 16)
#       define R300_SRC_BLEND_GL_SRC_COLOR           (34 << 16)
#       define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16)
#       define R300_SRC_BLEND_GL_DST_COLOR           (36 << 16)
#       define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16)
#       define R300_SRC_BLEND_GL_SRC_ALPHA           (38 << 16)
#       define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16)
#       define R300_SRC_BLEND_GL_DST_ALPHA           (40 << 16)
#       define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16)
#       define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE  (42 << 16)
#       define R300_SRC_BLEND_MASK                   (63 << 16)
#       define R300_DST_BLEND_GL_ZERO                (32 << 24)
#       define R300_DST_BLEND_GL_ONE                 (33 << 24)
#       define R300_DST_BLEND_GL_SRC_COLOR           (34 << 24)
#       define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24)
#       define R300_DST_BLEND_GL_DST_COLOR           (36 << 24)
#       define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24)
#       define R300_DST_BLEND_GL_SRC_ALPHA           (38 << 24)
#       define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24)
#       define R300_DST_BLEND_GL_DST_ALPHA           (40 << 24)
#       define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24)
#       define R300_DST_BLEND_MASK                   (63 << 24)
#define R300_RB3D_COLORMASK                 0x4E0C
#       define R300_COLORMASK0_B                 (1<<0)
#       define R300_COLORMASK0_G                 (1<<1)
#       define R300_COLORMASK0_R                 (1<<2)
#       define R300_COLORMASK0_A                 (1<<3)

// BEGIN: Vertex program instruction set
// Every instruction is four dwords long:
//  DWORD 0: output and opcode
//  DWORD 1: first argument
//  DWORD 2: second argument
//  DWORD 3: third argument
//
// Notes:
//  - ABS r, a is implemented as MAX r, a, -a
//  - MOV is implemented as ADD to zero
//  - XPD is implemented as MUL + MAD
//  - FLR is implemented as FRC + ADD
//  - apparently, fglrx tries to schedule instructions so that there is at least
//    one instruction between the write to a temporary and the first read
//    from said temporary; however, violations of this scheduling are allowed
//  - register indices seem to be unrelated with OpenGL aliasing to conventional state
//  - only one attribute and one parameter can be loaded at a time; however, the
//    same attribute/parameter can be used for more than one argument
//  - the second software argument for POW is the third hardware argument (no idea why)
//  - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
//
// There is some magic surrounding LIT:
// The single argument is replicated across all three inputs, but swizzled:
//  First argument: xyzy
//  Second argument: xyzx
//  Third argument: xyzw
// Whenever the result is used later in the fragment program, fglrx forces x and w
// to be 1.0 in the input selection; I don't know whether this is strictly necessary
#define R300_VPI_OUT_OP_DOT                     (1 << 0)
#define R300_VPI_OUT_OP_MUL                     (2 << 0)
#define R300_VPI_OUT_OP_ADD                     (3 << 0)
#define R300_VPI_OUT_OP_MAD                     (4 << 0)
#define R300_VPI_OUT_OP_FRC                     (6 << 0)
#define R300_VPI_OUT_OP_MAX                     (7 << 0)
#define R300_VPI_OUT_OP_MIN                     (8 << 0)
#define R300_VPI_OUT_OP_SGE                     (9 << 0)
#define R300_VPI_OUT_OP_SLT                     (10 << 0)
#define R300_VPI_OUT_OP_EXP                     (65 << 0)
#define R300_VPI_OUT_OP_LOG                     (66 << 0)
#define R300_VPI_OUT_OP_LIT                     (68 << 0)
#define R300_VPI_OUT_OP_POW                     (69 << 0)
#define R300_VPI_OUT_OP_RCP                     (70 << 0)
#define R300_VPI_OUT_OP_RSQ                     (72 << 0)
#define R300_VPI_OUT_OP_EX2                     (75 << 0)
#define R300_VPI_OUT_OP_LG2                     (76 << 0)
#define R300_VPI_OUT_OP_MAD_2                   (128 << 0)

#define R300_VPI_OUT_REG_CLASS_TEMPORARY        (0 << 8)
#define R300_VPI_OUT_REG_CLASS_RESULT           (2 << 8)
#define R300_VPI_OUT_REG_CLASS_MASK             (31 << 8)

#define R300_VPI_OUT_REG_INDEX_SHIFT            13
#define R300_VPI_OUT_REG_INDEX_MASK             (31 << 13) // GUESS based on fglrx native limits

#define R300_VPI_OUT_WRITE_X                    (1 << 20)
#define R300_VPI_OUT_WRITE_Y                    (1 << 21)
#define R300_VPI_OUT_WRITE_Z                    (1 << 22)
#define R300_VPI_OUT_WRITE_W                    (1 << 23)

#define R300_VPI_IN_REG_CLASS_TEMPORARY         (0 << 0)
#define R300_VPI_IN_REG_CLASS_ATTRIBUTE         (1 << 0)
#define R300_VPI_IN_REG_CLASS_PARAMETER         (2 << 0)
#define R300_VPI_IN_REG_CLASS_NONE              (9 << 0)
#define R300_VPI_IN_REG_CLASS_MASK              (31 << 0) // GUESS

#define R300_VPI_IN_REG_INDEX_SHIFT             5
#define R300_VPI_IN_REG_INDEX_MASK              (255 << 5) // GUESS based on fglrx native limits

// The R300 can select components from the input register arbitrarily.
// Use the following constants, shifted by the component shift you
// want to select
#define R300_VPI_IN_SELECT_X    0
#define R300_VPI_IN_SELECT_Y    1
#define R300_VPI_IN_SELECT_Z    2
#define R300_VPI_IN_SELECT_W    3
#define R300_VPI_IN_SELECT_ZERO 4
#define R300_VPI_IN_SELECT_ONE  5
#define R300_VPI_IN_SELECT_MASK 7

#define R300_VPI_IN_X_SHIFT                     13
#define R300_VPI_IN_Y_SHIFT                     16
#define R300_VPI_IN_Z_SHIFT                     19
#define R300_VPI_IN_W_SHIFT                     22

#define R300_VPI_IN_NEG_X                       (1 << 25)
#define R300_VPI_IN_NEG_Y                       (1 << 26)
#define R300_VPI_IN_NEG_Z                       (1 << 27)
#define R300_VPI_IN_NEG_W                       (1 << 28)
// END

Attachment: pgpaEhGpJo3yT.pgp
Description: PGP signature

Reply via email to