Index: [thread] [date] [subject] [author]
  From: James Simmons <jsimmons@edgeglobal.com>
  To  : ggi-develop <ggi-develop@eskimo.com>
  Date: Wed, 4 Aug 1999 22:55:29 -0400 (EDT)

Accels and /dev/gfx.

  Wow!! What a long and great thread. Well the ping pong buffer sounds
like the way to go. I though about the generic buffer commands. Its would
bloat the drivers to much. What I was think of was mapping a clone of
accel register space to userland. A regular piece of memmory. LibGGI
should take care of the translations of graphics functions like Triangle
to which register. As pointed out for some cards this would be to much of
a mess and would have impact on performace if we place this into the
kernel. Good example was the Virge card. First we would filter any bad
commands then we would swap that memory into kernel space. 

   As for the flushing of the accel commands before the ping pong buffers
are full. I saw alot of people discussing a a ioctl for this. Why? Did you
forget about msync? With the idea of a pseudo mmap accel region a msync
call would actually flush the commands to the kernel. I used this idea
in several programs. I wrote a program that mmaped a regular file. The
reason I did this was because I could alter the file in memory not the
file on the HD. Once I was done I ummap the file. The file was never truly
touched. Now we could something very similar with /dev/gfx. He we mmap the
psuedo accel buffer and then use msync to actually write the information
in the mmap to the real file, in this case the accel engine instead of a
file on the HD. Of course if you program say FG_COLOR register and
reprogram it again then flush you lose the first FG_COLOR information. Of
course this just requires proper graphics programming. 

  What we really need to do is ask ourselves what are all the possible
ways accel information can be passed to the kernel and do all of these
work well with ping pong buffers. From what I can see you have FIFOs,
DMAs, and plain MMIO registers. Did I miss any? The next question is what
can trigger a flush of the ping pong buffers. Their is of course the
manual way. Then their is waterlevel irqs, vbl. Any others beside the
page fault method I missed? Now for the page fault method. Well if its
just a mmap of psuedo MMIO registers is the page fault method the best
method or just using msync. For things like FIFOs which I believe use 
waterlevel irqs should we use a empty msync function. What about cards
that support FIFOs and MMIO registers? We need to really group together
all the possiblities. 

  As for using no_page for ping pong buffers. Yes you can. The nopage
function can also control the write access of these pages. I wonder if the 
protect and advise functions are now used for vma_ops. You have to be
careful with using nopage and mmap. You need to make sure not to call
extensively remap_page_range from fops->mmap. Here is a example of how
to set it up 

static struct vm_operations_struct simple_vm_ops = {
	NULL, NULL, NULL, NULL, NULL, NULL, simple_nopage,
};

unsigned long simple_nopage(struct vm_area_struct (vma, ... )
{
   pgd_t *pgd; pmd_t *pmd; pte_t *pte;
   
   /* int remap_page_range(virt_add, phys_add, size, protection); */
   remap_page_range(address & PAGE_MASK, address - vma->vm_start +
vma->vm_offset, PAGE_SIZE, vma->vm_page_prot);
   /* Now return its address to the caller */
   pgd = pgd_offset(current->mm, address);
   pmd = pmd_offset(pgd, page);
   pte = pte_offset(pmd, page);
   return pte_page(*pte);             /* this is the physical address */
}

simple_mmap(....) 
{
   vma->vma_ops = &simple_vm_ops;
   vma_vm_inode = inode;
   inode->i_count++;
   return 0;
} 	

If nopage method is left NULL the kernel code that handles pages faults
maps the zero page to the faulty virtual address. Therefore if you call
mremap and their is no nopage you end up with zero pages instead of a seg
fault. The above code is a example and I'm tired. A better way would be
memory emthod directly returned the physical address, bypassing
remap_page_range. 


P.S.
  Kernel side. After much debate I believe I have won the debate on VC
switching and /dev/fb. On a open(/dev/fb..) VC switching will be disabled
in 2.3.x kernels. They realize that with the upcoming cards demanding
userland applications to catch VT switchings and saving the framebuffer is
going to be impratical. I gave the example with the FireGL 5000 cards
(http://www.es.com). They have 56 megs of on board RAM. Now when linux
goes multiheaded and a big company has 8 of these cards and each person is
doing VT switching well you see the math. 32 VC * 8 cards * 56 Megs. You
see that you can have enough free RAM or disk space to do VT switching of
cards like this. Cards like this are going to be the future, the very near
future. 

P.S.S 
  The console code. Well it me verses Mares. Mares believes you can do
multiheadedness with the current console code. He thinks all that needs to
be done was a few lines of code to be changes. I told he was nuts. He
also wants to impliment explict locking of the VT for VT switching. You
need to lock the VT manually before you do a console switch. Then you
unlock the VT after th console switch. He thinks this will cure all the
race conditions that can occur with the current console code.



Index: [thread] [date] [subject] [author]