nouveau: Make the state cache hierarchical.
This commit is contained in:
@@ -31,6 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#include "nouveau_context.h"
|
||||
#include "nouveau_ctrlreg.h"
|
||||
#include "nouveau_state_cache.h"
|
||||
|
||||
//#define NOUVEAU_RING_DEBUG
|
||||
//#define NOUVEAU_STATE_CACHE_DISABLE
|
||||
@@ -114,6 +115,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa);
|
||||
#define OUT_RING_CACHE(n) do { \
|
||||
if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \
|
||||
} \
|
||||
nmesa->state_cache.current_pos++; \
|
||||
@@ -122,6 +124,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa);
|
||||
#define OUT_RING_CACHEf(n) do { \
|
||||
if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \
|
||||
nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \
|
||||
nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \
|
||||
(*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\
|
||||
} \
|
||||
nmesa->state_cache.current_pos++; \
|
||||
|
||||
@@ -25,6 +25,8 @@ void nouveau_state_cache_flush(nouveauContextPtr nmesa)
|
||||
do
|
||||
{
|
||||
// jump to a dirty state
|
||||
while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
|
||||
i=(i&~(NOUVEAU_STATE_CACHE_HIER_SIZE-1))+NOUVEAU_STATE_CACHE_HIER_SIZE;
|
||||
while((nmesa->state_cache.atoms[i].dirty==0)&&(i<NOUVEAU_STATE_CACHE_ENTRIES))
|
||||
i++;
|
||||
|
||||
@@ -42,11 +44,14 @@ void nouveau_state_cache_flush(nouveauContextPtr nmesa)
|
||||
{
|
||||
OUT_RING(nmesa->state_cache.atoms[i+j].value);
|
||||
nmesa->state_cache.atoms[i+j].dirty=0;
|
||||
if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0)
|
||||
nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
|
||||
}
|
||||
i+=run;
|
||||
}
|
||||
}
|
||||
while(i<NOUVEAU_STATE_CACHE_ENTRIES);
|
||||
nmesa->state_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#include "mtypes.h"
|
||||
|
||||
#define NOUVEAU_STATE_CACHE_ENTRIES 2048
|
||||
// size of a dirty requests block
|
||||
// you can play with that and tune the value to increase/decrease performance
|
||||
// but keep it a power of 2 !
|
||||
#define NOUVEAU_STATE_CACHE_HIER_SIZE 32
|
||||
|
||||
typedef struct nouveau_state_atom_t{
|
||||
uint32_t value;
|
||||
@@ -14,8 +18,10 @@ typedef struct nouveau_state_atom_t{
|
||||
typedef struct nouveau_state_cache_t{
|
||||
nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES];
|
||||
uint32_t current_pos;
|
||||
// hierarchical dirty flags
|
||||
uint8_t hdirty[NOUVEAU_STATE_CACHE_ENTRIES/NOUVEAU_STATE_CACHE_HIER_SIZE];
|
||||
// master dirty flag
|
||||
uint32_t dirty;
|
||||
uint8_t dirty;
|
||||
}nouveau_state_cache;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user