summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_gs_state.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-12-14 11:02:48 -0800
committerEric Anholt <eric@anholt.net>2007-12-14 11:04:26 -0800
commit38bad7677e57d629eeffd4ef39a7fc254db12735 (patch)
tree977b9f821b6c8a9ef166e0533c7a2664a72cffcb /src/mesa/drivers/dri/i965/brw_gs_state.c
parent0037ad4186c11267d85fcde378be79eb6acf74f3 (diff)
downloadexternal_mesa3d-38bad7677e57d629eeffd4ef39a7fc254db12735.zip
external_mesa3d-38bad7677e57d629eeffd4ef39a7fc254db12735.tar.gz
external_mesa3d-38bad7677e57d629eeffd4ef39a7fc254db12735.tar.bz2
[965] Replace the state cache suballocator with direct dri_bufmgr use.
The user-space suballocator that was used avoided relocation computations by using the general and surface state base registers and allocating those types of buffers out of pools built on top of single buffer objects. It also avoided calls into the buffer manager for these small state allocations, since only one buffer object was being used. However, the buffer allocation cost appears to be low, and with relocation caching, computing relocations for buffers is essentially free. Additionally, implementing the suballocator required a don't-fence-subdata flag to disable waiting on buffer maps so that writing new data didn't block on rendering using old data, and careful handling when mapping to update old data (which we need to do for unavoidable relocations with FBOs). More importantly, when the suballocator filled, it had no replacement algorithm and just threw out all of the contents and forced them to be recomputed, which is a significant cost. This is the first step, which just changes the buffer type, but doesn't yet improve the hash table to not result in full recompute on overflow. Because the buffers are all allocated out of the general buffer allocator, we can no longer use the general/surface state bases to avoid relocations, and they are set to 0 instead.
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_gs_state.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_state.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index 5db4dd4..6bbf11e 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -48,7 +48,8 @@ static void upload_gs_unit( struct brw_context *brw )
if (brw->gs.prog_active) {
gs.thread0.grf_reg_count =
ALIGN(brw->gs.prog_data->total_grf, 16) / 16 - 1;
- gs.thread0.kernel_start_pointer = brw->gs.prog_gs_offset >> 6;
+ /* reloc */
+ gs.thread0.kernel_start_pointer = brw->gs.prog_bo->offset >> 6;
gs.thread3.urb_entry_read_length = brw->gs.prog_data->urb_read_length;
}
else {
@@ -73,11 +74,25 @@ static void upload_gs_unit( struct brw_context *brw )
gs.thread3.const_urb_entry_read_offset = 0;
gs.thread3.const_urb_entry_read_length = 0;
gs.thread3.urb_entry_read_offset = 0;
-
- brw->gs.state_gs_offset = brw_cache_data( &brw->cache[BRW_GS_UNIT], &gs );
+ brw->gs.thread0_delta = gs.thread0.grf_reg_count << 1;
+
+ dri_bo_unreference(brw->gs.state_bo);
+ brw->gs.state_bo = brw_cache_data( &brw->cache, BRW_GS_UNIT, &gs,
+ &brw->gs.prog_bo, 1 );
}
+static void emit_reloc_gs_unit(struct brw_context *brw)
+{
+ if (brw->gs.prog_active) {
+ /* Emit GS program relocation */
+ dri_emit_reloc(brw->gs.state_bo,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ brw->gs.thread0_delta,
+ offsetof(struct brw_gs_unit_state, thread0),
+ brw->gs.prog_bo);
+ }
+}
const struct brw_tracked_state brw_gs_unit = {
.dirty = {
@@ -86,5 +101,6 @@ const struct brw_tracked_state brw_gs_unit = {
BRW_NEW_URB_FENCE),
.cache = CACHE_NEW_GS_PROG
},
- .update = upload_gs_unit
+ .update = upload_gs_unit,
+ .emit_reloc = emit_reloc_gs_unit,
};