Hello Vladimir,
1) It does not appear to be R300 specific - why doesn't similar Radeon ioctl work ? Also, I would imagine that this would require a change in r300 driver to work, wouldn't it ?
No, I suspected that it wasn't r300 specific actually, all the code does is write to a scratch register. So perhaps I should've just hooked up a R300_* ioctl number to the radeon code.
It only seems to occur after the reference counts for all the dma buffers hit
2) I was able to play Quake for somewhat prolonged periods, I don't think this would have really worked if aging was truly broken, though, maybe, I am wrong on this one.
Would you have a test app that shows brokenness ? Perhaps something that uses a lot of textures once.
zero. After that, no more r300AllocDmaRegion calls are successful.
The code I was referring to was r300_dri hacked up to use r300AllocDmaRegion
to grab buffers for vertex data, rather than using rsp->gartTextures.map to
store the data. It was just a little experiment I was trying, I've attached a diff
so you can see what happens for yourself, I may have missed something
important.
In r300ReleaseDmaRegion there is a #if/#endif to either use the ioctl or not.
One more thing, I'm not sure how to find the gart offset of the vertex/indirect
buffers, I've been hardcoding the value for now (r300_ioctl.h::GET_START),
you may need to look in your X log for the handle as it might differ from mine.
glxgears looks a little broken using this aswell, I have some random colours across the faces of the gears.
Anyhow, it was a little experiment I was doing to see how to implement vertex buffers.
Ben Skeggs.
diff -Nur orig/r300_context.h mod/r300_context.h
--- orig/r300_context.h 2005-02-04 04:48:32.000000000 +1100
+++ mod/r300_context.h 2005-02-05 04:08:09.000000000 +1100
@@ -96,7 +96,11 @@
drmBufPtr buf;
};
-#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset +
\
+//#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset +
\
+ (rvb)->address - rmesa->dma.buf0_address + \
+ (rvb)->start)
+
+#define GET_START(rvb) (0xe0102000 + \
(rvb)->address - rmesa->dma.buf0_address + \
(rvb)->start)
diff -Nur orig/r300_ioctl.c mod/r300_ioctl.c
--- orig/r300_ioctl.c 2005-02-02 02:46:23.000000000 +1100
+++ mod/r300_ioctl.c 2005-02-08 03:02:21.000000000 +1100
@@ -414,7 +414,7 @@
if (rmesa->dma.flush)
rmesa->dma.flush(rmesa);
-
+#if 1
if (--region->buf->refcount == 0) {
drm_radeon_cmd_header_t *cmd;
@@ -424,13 +424,15 @@
cmd =
(drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa,
- sizeof(*cmd),
+ sizeof(*cmd) /
4,
__FUNCTION__);
- cmd->dma.cmd_type = RADEON_CMD_DMA_DISCARD;
+ cmd->dma.cmd_type = R300_CMD_DMA_DISCARD;
cmd->dma.buf_idx = region->buf->buf->idx;
FREE(region->buf);
+
rmesa->dma.nr_released_bufs++;
}
+#endif
region->buf = 0;
region->start = 0;
diff -Nur orig/r300_render.c mod/r300_render.c
--- orig/r300_render.c 2005-02-04 06:51:57.000000000 +1100
+++ mod/r300_render.c 2005-02-08 03:10:41.149064384 +1100
@@ -381,6 +381,8 @@
/* vertex buffer implementation */
/* We use the start part of GART texture buffer for vertices */
+ static struct r300_dma_region rvb[8];
+ static int nr_rvb = 0;
static void upload_vertex_buffer(r300ContextPtr rmesa, GLcontext *ctx)
@@ -394,33 +396,38 @@
/* A hack - we don't want to overwrite vertex buffers, so we
just use AGP space for them.. Fix me ! */
+#if 0
static int offset=0;
if(offset>2*1024*1024){
//fprintf(stderr, "Wrapping agp vertex buffer offset\n");
offset=0;
}
+#endif
+
/* Not the most efficient implementation, but, for now, I just want
something that
works */
/* to do - make single memcpy per column (is it possible ?) */
/* to do - use dirty flags to avoid redundant copies */
#define UPLOAD_VECTOR(v)\
{ \
+ r300AllocDmaRegion(rmesa, &rvb[nr_rvb], v->stride*VB->Count,
4); \
/* Is the data dirty ? */ \
if (v->flags & ((1<<v->size)-1)) { \
/* fprintf(stderr, "size=%d vs stride=%d\n", v->size,
v->stride); */ \
if(v->size*4==v->stride){\
/* fast path */ \
- memcpy(rsp->gartTextures.map+offset, v->data,
v->stride*VB->Count); \
+ memcpy(rvb[nr_rvb].address + rvb[nr_rvb].start,
v->data, v->stride*VB->Count); \
} else { \
for(i=0;i<VB->Count;i++){ \
/* copy one vertex at a time*/ \
-
memcpy(rsp->gartTextures.map+offset+i*v->size*4, VEC_ELT(v, GLfloat, i),
v->size*4); \
+ memcpy(rvb[nr_rvb].address +
rvb[nr_rvb].start + (i*v->size*4), VEC_ELT(v, GLfloat, i), v->size*4); \
} \
} \
/* v->flags &= ~((1<<v->size)-1);*/ \
} \
- rmesa->state.aos[idx].offset=rsp->gartTextures.handle+offset; \
- offset+=v->size*4*VB->Count; \
+/* rmesa->state.aos[idx].offset=rsp->gartTextures.handle+offset;
*/ \
+ rmesa->state.aos[idx].offset=GET_START(&rvb[nr_rvb++]); \
+/* offset+=v->size*4*VB->Count; */ \
idx++; \
}
@@ -489,8 +496,7 @@
if (RADEON_DEBUG == DEBUG_PRIMS)
fprintf(stderr, "%s\n", __FUNCTION__);
-
-
+
reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
e32(0x0000000a);
@@ -498,13 +504,13 @@
e32(0x00000003);
r300_setup_routing(ctx, GL_FALSE);
-
r300EmitState(rmesa);
+ upload_vertex_buffer(rmesa, ctx);
+
/* setup array of structures data */
- LOCK_HARDWARE(&(rmesa->radeon));
- upload_vertex_buffer(rmesa, ctx);
+ LOCK_HARDWARE(&(rmesa->radeon));
//fprintf(stderr, "Using %d AOS arrays\n", n_arrays);
for(i=0; i < VB->PrimitiveCount; i++){
@@ -528,12 +534,17 @@
e32(0x00000003);
end_3d(PASS_PREFIX_VOID);
+
+ UNLOCK_HARDWARE(&(rmesa->radeon));
/* Flush state - we are done drawing.. */
- r300FlushCmdBufLocked(ctx, __FUNCTION__);
- radeonWaitForIdleLocked(&(rmesa->radeon));
-
- UNLOCK_HARDWARE(&(rmesa->radeon));
+ //r300FlushCmdBuf(ctx, __FUNCTION__);
+
+ for (i=0;i<nr_rvb;i++) {
+ r300ReleaseDmaRegion(rmesa, &rvb[i], __FUNCTION__);
+ }
+ nr_rvb = 0;
+
return GL_FALSE;
}
@@ -558,7 +569,7 @@
#if 1
- #if 1
+ #if 0
return r300_run_immediate_render(ctx, stage);
#else
return r300_run_vb_render(ctx, stage);
