[Mesa-dev] [PATCH] i965: Allocate the whole URB to the VS and fix calculations for Gen6.

Kenneth Graunke kenneth at whitecape.org
Tue Apr 12 15:42:06 PDT 2011


Since we never enable the GS on Sandybridge, there's no need to allocate
it any URB space.

Furthermore, the previous calculation was incorrect: it neglected to
multiply by nr_vs_entries, instead comparing whether twice the size of
a single VS URB entry was bigger than the entire URB space.  It also
neglected to take into account that vs_size is in units of 128 byte
blocks, while urb_size is in bytes.

Despite the above problems, the calculations resulted in an acceptable
programming of the URB in most cases, at least on GT2.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_context.c |    5 +++-
 src/mesa/drivers/dri/i965/brw_context.h |    5 +++-
 src/mesa/drivers/dri/i965/gen6_urb.c    |   34 +++++++++++++++---------------
 3 files changed, 25 insertions(+), 19 deletions(-)

v. "This time for sure!"

I moved the IS_GT1/GT2 checks to brw_context.c, where they belong,
and introduced new fields for the maximum number of VS/GS URB entries.
I don't currently set max_gs_entries because (a) we don't care yet, and
(b) the numbers in the documentation seem suspiciously like typos.

I also use ROUND_DOWN_TO again, now that it's fixed.

I haven't tested this patch yet since the Linux install on my Sandybridge
system is hosed.  I'll obviously do that before pushing.

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index a74ba5c..230d326 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -182,7 +182,6 @@ GLboolean brwCreateContext( int api,
 
    /* WM maximum threads is number of EUs times number of threads per EU. */
    if (intel->gen >= 6) {
-      brw->urb.size = 1024;
       if (IS_GT2(intel->intelScreen->deviceID)) {
 	 /* This could possibly be 80, but is supposed to require
 	  * disabling of WIZ hashing (bit 6 of GT_MODE, 0x20d0) and a
@@ -190,9 +189,13 @@ GLboolean brwCreateContext( int api,
 	  */
 	 brw->wm_max_threads = 40;
 	 brw->vs_max_threads = 60;
+	 brw->urb.size = 64;            /* volume 5c.5 section 5.1 */
+	 brw->urb.max_vs_handles = 128; /* volume 2a (see 3DSTATE_URB) */
       } else {
 	 brw->wm_max_threads = 40;
 	 brw->vs_max_threads = 24;
+	 brw->urb.size = 32;            /* volume 5c.5 section 5.1 */
+	 brw->urb.max_vs_handles = 256; /* volume 2a (see 3DSTATE_URB) */
       }
    } else if (intel->gen == 5) {
       brw->urb.size = 1024;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index f331236..140c89e 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -549,6 +549,9 @@ struct brw_context
 
       GLboolean constrained;
 
+      GLuint max_vs_handles;	/* Maximum number of VS handles */
+      GLuint max_gs_handles;	/* Maximum number of GS handles */
+
       GLuint nr_vs_entries;
       GLuint nr_gs_entries;
       GLuint nr_clip_entries;
@@ -560,7 +563,7 @@ struct brw_context
        * a number of 1024-bit (128-byte) rows.  Should be >= 1.
        */
       GLuint vs_size;
-/*       GLuint gs_size; */
+      GLuint gs_size;
 
       GLuint vs_start;
       GLuint gs_start;
diff --git a/src/mesa/drivers/dri/i965/gen6_urb.c b/src/mesa/drivers/dri/i965/gen6_urb.c
index c3819f9..909e1bb 100644
--- a/src/mesa/drivers/dri/i965/gen6_urb.c
+++ b/src/mesa/drivers/dri/i965/gen6_urb.c
@@ -34,26 +34,25 @@
 static void
 prepare_urb( struct brw_context *brw )
 {
-   int urb_size, max_urb_entry;
-   struct intel_context *intel = &brw->intel;
-
-   if (IS_GT1(intel->intelScreen->deviceID)) {
-	urb_size = 32 * 1024;
-	max_urb_entry = 128;
-   } else {
-	urb_size = 64 * 1024;
-	max_urb_entry = 256;
-   }
-
-   brw->urb.nr_vs_entries = max_urb_entry;
-   brw->urb.nr_gs_entries = max_urb_entry;
+   int nr_vs_entries;
 
    /* CACHE_NEW_VS_PROG */
    brw->urb.vs_size = MAX2(brw->vs.prog_data->urb_entry_size, 1);
 
-   if (2 * brw->urb.vs_size > urb_size)
-	   brw->urb.nr_vs_entries = brw->urb.nr_gs_entries = 
-		(urb_size ) / (2 * brw->urb.vs_size);
+   /* Calculate how many VS URB entries fit in the total URB size */
+   nr_vs_entries = (brw->urb.size * 1024) / (brw->urb.vs_size * 128);
+
+   if (nr_vs_entries > brw->urb.max_vs_handles)
+      nr_vs_entries = brw->urb.max_vs_handles;
+
+   /* According to volume 2a, nr_vs_entries must be a multiple of 4. */
+   brw->urb.nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, 4);
+
+   /* Since we currently don't support Geometry Shaders, we always put the
+    * GS unit in passthrough mode and don't allocate it any URB space.
+    */
+   brw->urb.nr_gs_entries = 0;
+   brw->urb.gs_size = 1; /* Incorrect, but with 0 GS entries it doesn't matter. */
 }
 
 static void
@@ -61,6 +60,7 @@ upload_urb(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
 
+   assert(brw->urb.nr_vs_entries >= 24);
    assert(brw->urb.nr_vs_entries % 4 == 0);
    assert(brw->urb.nr_gs_entries % 4 == 0);
    /* GS requirement */
@@ -70,7 +70,7 @@ upload_urb(struct brw_context *brw)
    OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
    OUT_BATCH(((brw->urb.vs_size - 1) << GEN6_URB_VS_SIZE_SHIFT) |
 	     ((brw->urb.nr_vs_entries) << GEN6_URB_VS_ENTRIES_SHIFT));
-   OUT_BATCH(((brw->urb.vs_size - 1) << GEN6_URB_GS_SIZE_SHIFT) |
+   OUT_BATCH(((brw->urb.gs_size - 1) << GEN6_URB_GS_SIZE_SHIFT) |
 	     ((brw->urb.nr_gs_entries) << GEN6_URB_GS_ENTRIES_SHIFT));
    ADVANCE_BATCH();
 }
-- 
1.7.4.4



More information about the mesa-dev mailing list