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
pgpaEhGpJo3yT.pgp
Description: PGP signature