summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/r300/r300_maos.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r300/r300_maos.c')
-rw-r--r--src/mesa/drivers/dri/r300/r300_maos.c396
1 files changed, 378 insertions, 18 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_maos.c b/src/mesa/drivers/dri/r300/r300_maos.c
index 1908ac07acd..52827c2d5dc 100644
--- a/src/mesa/drivers/dri/r300/r300_maos.c
+++ b/src/mesa/drivers/dri/r300/r300_maos.c
@@ -50,6 +50,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_maos.h"
#include "r300_ioctl.h"
+#ifdef USER_BUFFERS
+#include "radeon_mm.h"
+#endif
+
#define DEBUG_ALL DEBUG_VERTS
@@ -173,15 +177,11 @@ static void emit_vector(GLcontext * ctx,
fprintf(stderr, "%s count %d size %d stride %d\n",
__FUNCTION__, count, size, stride);
- if(r300IsGartMemory(rmesa, data, size*stride)){
- rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
- rvb->start = (char *)data - rvb->address;
+ if(r300IsGartMemory(rmesa, data, /*(count-1)*stride */ 4)){
+ rvb->address = data;
+ rvb->start = 0;
rvb->aos_offset = r300GartOffsetFromVirtual(rmesa, data);
-
- if(stride == 0)
- rvb->aos_stride = 0;
- else
- rvb->aos_stride = stride / 4;
+ rvb->aos_stride = stride / 4 ;
rvb->aos_size = size;
return;
@@ -226,26 +226,30 @@ static void emit_vector(GLcontext * ctx,
}
-void r300EmitElts(GLcontext * ctx, GLuint *elts, unsigned long n_elts)
+void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts, int elt_size)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_dma_region *rvb=&rmesa->state.elt_dma;
- unsigned short int *out;
- int i;
+ void *out;
- if(r300IsGartMemory(rmesa, elts, n_elts*sizeof(unsigned short int))){
+ assert(elt_size == 2 || elt_size == 4);
+
+ if(r300IsGartMemory(rmesa, elts, n_elts * elt_size)){
rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
- rvb->start = (char *)elts - rvb->address;
+ rvb->start = ((char *)elts) - rvb->address;
rvb->aos_offset = rmesa->radeon.radeonScreen->gart_texture_offset + rvb->start;
+
return ;
+ }else if(r300IsGartMemory(rmesa, elts, 1)){
+ WARN_ONCE("Pointer not within GART memory!\n");
+ exit(1);
}
- r300AllocDmaRegion(rmesa, rvb, n_elts*sizeof(unsigned short int), 2);
+ r300AllocDmaRegion(rmesa, rvb, n_elts * elt_size, elt_size);
+ rvb->aos_offset = GET_START(rvb);
- out = (unsigned short int *)(rvb->address + rvb->start);
-
- for(i=0; i < n_elts; i++)
- out[i]=(unsigned short int)elts[i];
+ out = rvb->address + rvb->start;
+ memcpy(out, elts, n_elts * elt_size);
}
/* Emit vertex data to GART memory (unless immediate mode)
@@ -549,6 +553,362 @@ void r300EmitArrays(GLcontext * ctx, GLboolean immd)
rmesa->state.aos_count = nr;
}
+#ifdef RADEON_VTXFMT_A
+void r300EmitArraysVtx(GLcontext * ctx, GLboolean immd)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ r300ContextPtr r300 = rmesa;
+ struct radeon_vertex_buffer *VB = &rmesa->state.VB;
+ //struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ GLuint nr = 0;
+ GLuint count = VB->Count;
+ GLuint dw,mask;
+ GLuint vic_1 = 0; /* R300_VAP_INPUT_CNTL_1 */
+ GLuint aa_vap_reg = 0; /* VAP register assignment */
+ GLuint i;
+ GLuint inputs = 0;
+
+
+#define CONFIGURE_AOS(r, f, v, sz, cn) { \
+ if (RADEON_DEBUG & DEBUG_STATE) \
+ fprintf(stderr, "Enabling "#v "\n"); \
+ if (++nr >= R300_MAX_AOS_ARRAYS) { \
+ fprintf(stderr, "Aieee! AOS array count exceeded!\n"); \
+ exit(-1); \
+ } \
+ \
+ if (hw_tcl_on == GL_FALSE) \
+ rmesa->state.aos[nr-1].aos_reg = aa_vap_reg++; \
+ rmesa->state.aos[nr-1].aos_format = f; \
+ if (immd) { \
+ rmesa->state.aos[nr-1].aos_size = 4; \
+ rmesa->state.aos[nr-1].aos_stride = 4; \
+ rmesa->state.aos[nr-1].aos_offset = 0; \
+ } else { \
+ emit_vector(ctx, \
+ &rmesa->state.aos[nr-1], \
+ v.data, \
+ sz, \
+ v.stride, \
+ cn); \
+ rmesa->state.vap_reg.r=rmesa->state.aos[nr-1].aos_reg; \
+ } \
+}
+
+ if (hw_tcl_on) {
+ GLuint InputsRead = CURRENT_VERTEX_SHADER(ctx)->InputsRead;
+ struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
+ if (InputsRead & (1<<VERT_ATTRIB_POS)) {
+ inputs |= _TNL_BIT_POS;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_POS];
+ }
+ if (InputsRead & (1<<VERT_ATTRIB_NORMAL)) {
+ inputs |= _TNL_BIT_NORMAL;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_NORMAL];
+ }
+ if (InputsRead & (1<<VERT_ATTRIB_COLOR0)) {
+ inputs |= _TNL_BIT_COLOR0;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR0];
+ }
+ if (InputsRead & (1<<VERT_ATTRIB_COLOR1)) {
+ inputs |= _TNL_BIT_COLOR1;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_COLOR1];
+ }
+ if (InputsRead & (1<<VERT_ATTRIB_FOG)) {
+ inputs |= _TNL_BIT_FOG;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_FOG];
+ }
+ if(ctx->Const.MaxTextureUnits > 8) { /* Not sure if this can even happen... */
+ fprintf(stderr, "%s: Cant handle that many inputs\n", __FUNCTION__);
+ exit(-1);
+ }
+ for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
+ if (InputsRead & (1<<(VERT_ATTRIB_TEX0+i))) {
+ inputs |= _TNL_BIT_TEX0<<i;
+ rmesa->state.aos[nr++].aos_reg = prog->inputs[VERT_ATTRIB_TEX0+i];
+ }
+ }
+ nr = 0;
+ } else {
+ inputs = TNL_CONTEXT(ctx)->render_inputs;
+ }
+ rmesa->state.render_inputs = inputs;
+
+ if (inputs & _TNL_BIT_POS) {
+ CONFIGURE_AOS(i_coords, AOS_FORMAT_FLOAT,
+ VB->AttribPtr[VERT_ATTRIB_POS],
+ immd ? 4 : VB->AttribPtr[VERT_ATTRIB_POS].size,
+ count);
+
+ vic_1 |= R300_INPUT_CNTL_POS;
+ }
+
+ if (inputs & _TNL_BIT_NORMAL) {
+ CONFIGURE_AOS(i_normal, AOS_FORMAT_FLOAT,
+ VB->AttribPtr[VERT_ATTRIB_NORMAL],
+ immd ? 4 : VB->AttribPtr[VERT_ATTRIB_NORMAL].size,
+ count);
+
+ vic_1 |= R300_INPUT_CNTL_NORMAL;
+ }
+
+ if (inputs & _TNL_BIT_COLOR0) {
+ int emitsize=4;
+
+ if (!immd) {
+ if (VB->AttribPtr[VERT_ATTRIB_COLOR0].size == 4 &&
+ (VB->AttribPtr[VERT_ATTRIB_COLOR0].stride != 0 ||
+ ((float*)VB->AttribPtr[VERT_ATTRIB_COLOR0].data)[3] != 1.0)) {
+ emitsize = 4;
+ } else {
+ emitsize = 3;
+ }//emitsize = VB->AttribPtr[VERT_ATTRIB_COLOR0].size;
+ }
+ if(VB->AttribPtr[VERT_ATTRIB_COLOR0].type == GL_UNSIGNED_BYTE)
+ emitsize = 1;
+
+ CONFIGURE_AOS(i_color[0], VB->AttribPtr[VERT_ATTRIB_COLOR0].type == GL_UNSIGNED_BYTE ? AOS_FORMAT_UBYTE : AOS_FORMAT_FLOAT_COLOR,
+ VB->AttribPtr[VERT_ATTRIB_COLOR0],
+ immd ? 4 : emitsize,
+ count);
+
+ vic_1 |= R300_INPUT_CNTL_COLOR;
+ }
+
+ if (inputs & _TNL_BIT_COLOR1) {
+ CONFIGURE_AOS(i_color[1], AOS_FORMAT_FLOAT_COLOR,
+ VB->AttribPtr[VERT_ATTRIB_COLOR1],
+ immd ? 4 : VB->AttribPtr[VERT_ATTRIB_COLOR1].size,
+ count);
+ }
+
+#if 0
+ if (inputs & _TNL_BIT_FOG) {
+ CONFIGURE_AOS( AOS_FORMAT_FLOAT,
+ VB->FogCoordPtr,
+ immd ? 4 : VB->FogCoordPtr->size,
+ count);
+ }
+#endif
+
+ r300->state.texture.tc_count = 0;
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (inputs & (_TNL_BIT_TEX0 << i)) {
+ CONFIGURE_AOS(i_tex[i], AOS_FORMAT_FLOAT,
+ VB->AttribPtr[VERT_ATTRIB_TEX0+i],
+ immd ? 4 : VB->AttribPtr[VERT_ATTRIB_TEX0+i].size,
+ count);
+
+ vic_1 |= R300_INPUT_CNTL_TC0 << i;
+ r300->state.texture.tc_count++;
+ }
+ }
+ for(i=0; i < nr; i++)
+ if(r300->state.aos[i].aos_format == 2){
+ assert(r300->state.aos[i].aos_size == 1);
+ r300->state.aos[i].aos_size=5;
+ }
+
+#define SHOW_INFO(n) do { \
+ if (RADEON_DEBUG & DEBUG_ALL) { \
+ fprintf(stderr, "RR[%d] - sz=%d, reg=%d, fmt=%d -- st=%d, of=0x%08x\n", \
+ n, \
+ r300->state.aos[n].aos_size, \
+ r300->state.aos[n].aos_reg, \
+ r300->state.aos[n].aos_format, \
+ r300->state.aos[n].aos_stride, \
+ r300->state.aos[n].aos_offset); \
+ } \
+} while(0);
+
+ /* setup INPUT_ROUTE */
+ R300_STATECHANGE(r300, vir[0]);
+ for(i=0;i+1<nr;i+=2){
+ SHOW_INFO(i)
+ SHOW_INFO(i+1)
+ dw=(r300->state.aos[i].aos_size-1)
+ | ((r300->state.aos[i].aos_reg)<<8)
+ | (r300->state.aos[i].aos_format<<14)
+ | (((r300->state.aos[i+1].aos_size-1)
+ | ((r300->state.aos[i+1].aos_reg)<<8)
+ | (r300->state.aos[i+1].aos_format<<14))<<16);
+
+ if(i+2==nr){
+ dw|=(1<<(13+16));
+ }
+ r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
+ }
+ if(nr & 1){
+ SHOW_INFO(nr-1)
+ dw=(r300->state.aos[nr-1].aos_size-1)
+ | (r300->state.aos[nr-1].aos_format<<14)
+ | ((r300->state.aos[nr-1].aos_reg)<<8)
+ | (1<<13);
+ r300->hw.vir[0].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
+ //fprintf(stderr, "vir0 dw=%08x\n", dw);
+ }
+ /* Set the rest of INPUT_ROUTE_0 to 0 */
+ //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[0].cmd[R300_VIR_CNTL_0+i]=(0x0);
+ ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->packet0.count = (nr+1)>>1;
+
+
+ /* Mesa assumes that all missing components are from (0, 0, 0, 1) */
+#define ALL_COMPONENTS ((R300_INPUT_ROUTE_SELECT_X<<R300_INPUT_ROUTE_X_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_Y<<R300_INPUT_ROUTE_Y_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_Z<<R300_INPUT_ROUTE_Z_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_W<<R300_INPUT_ROUTE_W_SHIFT))
+
+#define ALL_DEFAULT ((R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_X_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Y_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ZERO<<R300_INPUT_ROUTE_Z_SHIFT) \
+ | (R300_INPUT_ROUTE_SELECT_ONE<<R300_INPUT_ROUTE_W_SHIFT))
+
+ R300_STATECHANGE(r300, vir[1]);
+
+ for(i=0; i < nr; i++)
+ if(r300->state.aos[i].aos_format == 2){
+ assert(r300->state.aos[i].aos_size == 5);
+ r300->state.aos[i].aos_size=/*3*/4; /* XXX */
+ }
+
+
+ for(i=0;i+1<nr;i+=2){
+ /* do i first.. */
+ mask=(1<<(r300->state.aos[i].aos_size*3))-1;
+ dw=(ALL_COMPONENTS & mask)
+ | (ALL_DEFAULT & ~mask)
+ | R300_INPUT_ROUTE_ENABLE;
+
+ /* i+1 */
+ mask=(1<<(r300->state.aos[i+1].aos_size*3))-1;
+ dw|=(
+ (ALL_COMPONENTS & mask)
+ | (ALL_DEFAULT & ~mask)
+ | R300_INPUT_ROUTE_ENABLE
+ )<<16;
+
+ //fprintf(stderr, "vir1 dw=%08x\n", dw);
+ r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(i>>1)]=dw;
+ }
+ if(nr & 1){
+ mask=(1<<(r300->state.aos[nr-1].aos_size*3))-1;
+ dw=(ALL_COMPONENTS & mask)
+ | (ALL_DEFAULT & ~mask)
+ | R300_INPUT_ROUTE_ENABLE;
+ r300->hw.vir[1].cmd[R300_VIR_CNTL_0+(nr>>1)]=dw;
+ //fprintf(stderr, "vir1 dw=%08x\n", dw);
+ }
+ /* Set the rest of INPUT_ROUTE_1 to 0 */
+ //for(i=((count+1)>>1); i<8; i++)r300->hw.vir[1].cmd[R300_VIR_CNTL_0+i]=0x0;
+ ((drm_r300_cmd_header_t*)r300->hw.vir[1].cmd)->packet0.count = (nr+1)>>1;
+
+ /* Set up input_cntl */
+ /* I don't think this is needed for vertex buffers, but it doesn't hurt anything */
+ R300_STATECHANGE(r300, vic);
+ r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555; /* Hard coded value, no idea what it means */
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]=vic_1;
+
+ for(i=0; i < nr; i++)
+ if(r300->state.aos[i].aos_format == 2){
+ assert(r300->state.aos[i].aos_size == /*3*/4); /* XXX */
+ r300->state.aos[i].aos_size=1;
+ }
+#if 0
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]=0;
+
+ if(r300->state.render_inputs & _TNL_BIT_POS)
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS;
+
+ if(r300->state.render_inputs & _TNL_BIT_NORMAL)
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL;
+
+ if(r300->state.render_inputs & _TNL_BIT_COLOR0)
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR;
+
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++)
+ if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
+ r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
+#endif
+
+ /* Stage 3: VAP output */
+
+ R300_STATECHANGE(r300, vof);
+
+ r300->hw.vof.cmd[R300_VOF_CNTL_0]=0;
+ r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
+ if (hw_tcl_on){
+ GLuint OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->OutputsWritten;
+
+ if(OutputsWritten & (1<<VERT_RESULT_HPOS))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_COL0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+ /*if(OutputsWritten & (1<<VERT_RESULT_COL1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_BFC0))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
+ if(OutputsWritten & (1<<VERT_RESULT_BFC1))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
+ //if(OutputsWritten & (1<<VERT_RESULT_FOGC))
+
+ if(OutputsWritten & (1<<VERT_RESULT_PSIZ))
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++)
+ if(OutputsWritten & (1<<(VERT_RESULT_TEX0+i)))
+ r300->hw.vof.cmd[R300_VOF_CNTL_1] |= (4<<(3*i));
+ } else {
+ if(inputs & _TNL_BIT_POS)
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ if(inputs & _TNL_BIT_COLOR0)
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
+ if(inputs & _TNL_BIT_COLOR1)
+ r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++)
+ if(inputs & (_TNL_BIT_TEX0<<i))
+ r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
+ }
+
+ rmesa->state.aos_count = nr;
+}
+#endif
+
+#ifdef USER_BUFFERS
+void r300UseArrays(GLcontext * ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ int i;
+
+ if(rmesa->state.elt_dma.buf)
+ radeon_mm_use(rmesa, rmesa->state.elt_dma.buf->id);
+
+ for (i=0; i < rmesa->state.aos_count;i++) {
+ if (rmesa->state.aos[i].buf)
+ radeon_mm_use(rmesa, rmesa->state.aos[i].buf->id);
+ }
+
+#ifdef HW_VBOS
+
+#define USE_VBO(a) if (ctx->Array.a.BufferObj->Name && ctx->Array.a.Enabled) \
+ radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.a.BufferObj)->id)
+
+ if (ctx->Array.ElementArrayBufferObj->Name && ctx->Array.ElementArrayBufferObj->OnCard)
+ radeon_mm_use(rmesa, ((struct r300_buffer_object *)ctx->Array.ElementArrayBufferObj)->id);
+
+ USE_VBO(Vertex);
+ USE_VBO(Normal);
+ USE_VBO(Color);
+ USE_VBO(SecondaryColor);
+ USE_VBO(FogCoord);
+
+ for (i=0; i < MAX_TEXTURE_COORD_UNITS; i++)
+ USE_VBO(TexCoord[i]);
+#endif
+
+}
+#endif
+
void r300ReleaseArrays(GLcontext * ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);