Merge branch 'origin' into glsl-compiler-1
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_state_cache.c
1
2 #include "nouveau_state_cache.h"
3 #include "nouveau_context.h"
4 #include "nouveau_object.h"
5 #include "nouveau_fifo.h"
6
7 #define BEGIN_RING_NOFLUSH(subchannel,tag,size) do { \
8 if (nmesa->fifo.free <= (size)) \
9 WAIT_RING(nmesa,(size)); \
10 OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \
11 nmesa->fifo.free -= ((size) + 1); \
12 }while(0)
13
14 // flush all the dirty state
15 void nouveau_state_cache_flush(nouveauContextPtr nmesa)
16 {
17 int i=0;
18 int run=0;
19
20 // fast-path no state changes
21 if (!nmesa->state_cache.dirty)
22 return;
23 nmesa->state_cache.dirty=0;
24
25 do
26 {
27 // jump to a dirty state
28 while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
29 i=(i&~(NOUVEAU_STATE_CACHE_HIER_SIZE-1))+NOUVEAU_STATE_CACHE_HIER_SIZE;
30 while((nmesa->state_cache.atoms[i].dirty==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
31 i++;
32
33 // figure out a run of dirty values
34 run=0;
35 while((nmesa->state_cache.atoms[i+run].dirty)&&(i+run<NOUVEAU_STATE_CACHE_ENTRIES))
36 run++;
37
38 // output everything as a single run
39 if (run>0) {
40 int j;
41
42 BEGIN_RING_NOFLUSH(NvSub3D, i*4, run);
43 for(j=0;j<run;j++)
44 {
45 OUT_RING(nmesa->state_cache.atoms[i+j].value);
46 nmesa->state_cache.atoms[i+j].dirty=0;
47 if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0)
48 nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
49 }
50 i+=run;
51 }
52 }
53 while(i<NOUVEAU_STATE_CACHE_ENTRIES);
54 nmesa->state_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
55 }
56
57
58 // inits the state cache
59 void nouveau_state_cache_init(nouveauContextPtr nmesa)
60 {
61 int i;
62 for(i=0;i<NOUVEAU_STATE_CACHE_ENTRIES;i++)
63 {
64 nmesa->state_cache.atoms[i].dirty=0;
65 nmesa->state_cache.atoms[i].value=0xDEADBEEF; // nvidia cards like beef
66 }
67 nmesa->state_cache.dirty=0;
68 }
69