completed DMA buffer wraparounds. DMA acceleration is now stable on NV11 and NV43. Enjoy.. (still missing acc hooks will be setup asap.)

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10959 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen 2005-01-22 19:22:45 +00:00
parent c3a3ddf246
commit fc61675c5a
2 changed files with 76 additions and 31 deletions

View File

@ -26,9 +26,8 @@ blit
nVidia hardware info:
We should be able to do FIFO assignment setup changes on-the-fly now, using
all the engine-command-handles that are pre-defined on any FIFO channel.
We should be able to even setup new additional handles to previously unused engine
commands now, and DMA use should also be possible.
Also we should be able to setup new additional handles to previously unused
engine commands now.
*/
/* FIFO channel pointers */
@ -82,14 +81,12 @@ status_t nv_acc_init()
/* (setup caches) */
/* disable caches reassign */
ACCW(PF_CACHES, 0x00000000);
//fixme: set this up for DMA use one day..
/* PFIFO mode for all 32 channels is PIO (instead of DMA) */
ACCW(PF_MODE, 0x00000000);
/* cache1 push0 access disabled */
ACCW(PF_CACH1_PSH0, 0x00000000);
/* cache1 pull0 access disabled */
ACCW(PF_CACH1_PUL0, 0x00000000);
//fixme: set this up for DMA use one day..
/* cache1 push1 mode = pio (disable DMA use) */
ACCW(PF_CACH1_PSH1, 0x00000000);
/* cache1 DMA Put offset = 0 (b2-28) */
@ -100,10 +97,8 @@ status_t nv_acc_init()
* instance being b4-19 with baseadress NV_PRAMIN_CTX_0 (0x00700000). */
/* note:
* should point to a DMA definition in CTX register space (which is sort of RAM).
* This define tells the engine where the DMA cmd buffer is and what it's size is;
* inside that cmd buffer you'll find the engine handles for the FIFO channels,
* followed by actual issued engine commands. */
//fixme: set this up for DMA use one day..
* This define tells the engine where the DMA cmd buffer is and what it's size is.
* Inside that cmd buffer you'll find the actual issued engine commands. */
ACCW(PF_CACH1_DMAI, 0x00000000);
/* cache0 push0 access disabled */
ACCW(PF_CACH0_PSH0, 0x00000000);
@ -144,7 +139,6 @@ status_t nv_acc_init()
* use little endian */
ACCW(PF_CACH1_DMAF, 0x000f0078);
/* cache1 DMA push: b0=0 is access disabled */
//fixme: set this up for DMA use one day..
ACCW(PF_CACH1_DMAS, 0x00000000);
/* cache1 push0 access enabled */
ACCW(PF_CACH1_PSH0, 0x00000001);

View File

@ -61,8 +61,6 @@ status_t nv_acc_init_dma()
{
uint16 cnt;
uint32 surf_depth, patt_depth;
//fixme: move to shared info:
uint32 max;
/* a hanging engine only recovers from a complete power-down/power-up cycle */
NV_REG32(NV32_PWRUPCTRL) = 0x13110011;
@ -555,7 +553,7 @@ status_t nv_acc_init_dma()
}
/* all cards: */
/* setup some clipping: rect size is 32768 x 32768, probably max. setting */
/* setup clipping: rect size is 32768 x 32768, probably max. setting */
ACCW(ABS_UCLP_XMIN, 0x00000000);
ACCW(ABS_UCLP_YMIN, 0x00000000);
ACCW(ABS_UCLP_XMAX, 0x00007fff);
@ -584,9 +582,8 @@ status_t nv_acc_init_dma()
* instance being b4-19 with baseadress NV_PRAMIN_CTX_0 (0x00700000). */
/* note:
* should point to a DMA definition in CTX register space (which is sort of RAM).
* This define tells the engine where the DMA cmd buffer is and what it's size is;
* inside that cmd buffer you'll find the engine handles for the FIFO channels,
* followed by actual issued engine commands. */
* This define tells the engine where the DMA cmd buffer is and what it's size is.
* Inside that cmd buffer you'll find the actual issued engine commands. */
ACCW(PF_CACH1_DMAI, 0x0000114e);
/* cache0 push0 access disabled */
ACCW(PF_CACH0_PSH0, 0x00000000);
@ -679,11 +676,15 @@ status_t nv_acc_init_dma()
* one word is reserved at the end of the DMA buffer to be able to instruct the
* engine to do a buffer wrap-around!
* (DMA opcode 'noninc method': issue word $20000000.) */
/*si->dma.*/max = 8191;
//testing:
si->engine.dma.max = 2048 - 1;//8192 - 1;
/* note the current free space we have left in the DMA buffer */
si->engine.dma.free = /*si->dma.*/max - si->engine.dma.current /*+ 1*/;
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
/*** init FIFO via DMA command buffer. ***/
/* note:
* we know there's space enough in the command buffer to issue these commands,
* so no need to wait for room in there. */
si->engine.dma.cmdbuffer[si->engine.dma.current++] =
(NV_GENERAL_FIFO_CH0 | (1 << 18));
si->engine.dma.cmdbuffer[si->engine.dma.current++] =
@ -728,6 +729,9 @@ status_t nv_acc_init_dma()
// (0x80000000 | si->engine.fifo.handle[7]); /* Textured Triangle (3D only) */
(0x80000000 | si->engine.fifo.handle[0]);
/* update the current free space we have left in the DMA buffer */
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
//fixme: overlay should stay outside the DMA buffer, also add a failsafe
// space in between both functions as errors might hang the engine!
/*** Set pixel width ***/
@ -810,14 +814,55 @@ for (dummy = 0; dummy < 2; dummy++)
static status_t nv_acc_fifofree_dma(uint16 cmd_size)
{
//fixme: implement buffer wraparounds.. (buffer resets when full)
//for now only executing the first commands issued and drop exec after;
//this offers testing options already (depending on how much windows are visible,
//exec remains going say 30 seconds to a few minutes if only blits are enabled.
// if (si->dma.free >= cmd_size) return B_OK;
if ((si->engine.dma.current + cmd_size) < 8191) return B_OK;
//test:
uint32 dummy;
return B_ERROR;
if (si->engine.dma.free < cmd_size)
{
//test:
LOG(4,("ACC_FIFOFREE: level 1; free $%08x, max $%08x, current $%08x\n",
si->engine.dma.free, si->engine.dma.max, si->engine.dma.current ));
/* update to actual current situation (free is 'cached') */
// si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
/* check again if we have enough space */
// if (si->engine.dma.free < cmd_size)
{
//test:
LOG(4,("ACC_FIFOFREE: level 2\n"));
/* nope, so instruct DMA engine to reset the buffer when it's done */
si->engine.dma.cmdbuffer[si->engine.dma.current++] = 0x20000000;
/* reset our buffer pointer, so new commands will be placed at the
* beginning of the buffer. */
si->engine.dma.current = 0;
/* tell the engine to fetch the remaining command(s) in the DMA buffer
* that where not executed before. */
nv_start_dma();
/* fixme if needed:
* we are assuming here that a large part in the beginning of the DMA
* cmd buffer is already processed. If this is not true, we need to wait
* here until the engine becomes idle or so... */
//test:
//nv_acc_wait_idle_dma();
// {
/* snooze a bit so I do not hammer the bus */
// snooze (100);
// }
for (dummy = 0; dummy < 2; dummy++)
{
LOG(4,("ACC_DMA_WRAP: get $%08x\n", NV_REG32(NVACC_FIFO + NV_GENERAL_DMAGET +
si->engine.fifo.handle[(si->engine.fifo.ch_ptr[NV_ROP5_SOLID])])));
LOG(4,("ACC_DMA_WRAP: put $%08x\n", (si->engine.dma.put << 2)));
}
/* update the current free space we have left in the DMA buffer */
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
}
}
return B_OK;
}
static void nv_acc_cmd_dma(uint32 cmd, uint16 offset, uint16 size)
@ -836,6 +881,9 @@ static void nv_acc_cmd_dma(uint32 cmd, uint16 offset, uint16 size)
* to set a new adress if a gap exists between the previous one and the new one. */
si->engine.dma.cmdbuffer[si->engine.dma.current++] = ((size << 18) |
((si->engine.fifo.ch_ptr[cmd] + offset) & 0x0000fffc));
/* space left after issuing the current command is the cmd AND it's data */
si->engine.dma.free -= (size + 1);
}
/* fixme? (check this out..)
@ -886,6 +934,9 @@ void nv_acc_assert_fifo_dma(void)
(0x00000001 + (cnt * 0x00002000));
}
/* wait for room in fifo for new FIFO assigment cmds if needed. */
nv_acc_fifofree_dma(12);
/* program new FIFO assignments */
si->engine.dma.cmdbuffer[si->engine.dma.current++] =
(NV_GENERAL_FIFO_CH0 | (1 << 18));
@ -917,6 +968,9 @@ void nv_acc_assert_fifo_dma(void)
si->engine.dma.cmdbuffer[si->engine.dma.current++] =
(0x80000000 | si->engine.fifo.handle[5]); /* Bitmap */
/* update the current free space we have left in the DMA buffer */
si->engine.dma.free = si->engine.dma.max - si->engine.dma.current;
/* tell the engine to fetch and execute all (new) commands in the DMA buffer */
nv_start_dma();
}
@ -927,8 +981,7 @@ status_t nv_acc_setup_blit_dma()
{
/* setup solid pattern:
* wait for room in fifo for pattern cmd if needed. */
//fixme: testing..
if (nv_acc_fifofree_dma(7) != B_OK) return B_ERROR;
nv_acc_fifofree_dma(7);
/* now setup pattern (writing 7 32bit words) */
nv_acc_cmd_dma(NV_IMAGE_PATTERN, NV_IMAGE_PATTERN_SETSHAPE, 1);
@ -940,8 +993,7 @@ status_t nv_acc_setup_blit_dma()
si->engine.dma.cmdbuffer[si->engine.dma.current++] = 0xffffffff; /* SetPattern[1] */
/* ROP registers (Raster OPeration):
* wait for room in fifo for ROP cmd if needed. */
//fixme: testing..
if (nv_acc_fifofree_dma(2) != B_OK) return B_ERROR;
nv_acc_fifofree_dma(2);
/* now setup ROP (writing 2 32bit words) */
nv_acc_cmd_dma(NV_ROP5_SOLID, NV_ROP5_SOLID_SETROP5, 1);
@ -956,8 +1008,7 @@ status_t nv_acc_blit_dma(uint16 xs,uint16 ys,uint16 xd,uint16 yd,uint16 w,uint16
/* instruct engine what to blit:
* wait for room in fifo for blit cmd if needed. */
//fixme: testing..
if (nv_acc_fifofree_dma(4) != B_OK) return B_ERROR;
nv_acc_fifofree_dma(4);
/* now setup blit (writing 4 32bit words) */
nv_acc_cmd_dma(NV_IMAGE_BLIT, NV_IMAGE_BLIT_SOURCEORG, 3);