i965: Set up allocation of a VS scratch space if required.
authorEric Anholt <eric@anholt.net>
Sun, 7 Aug 2011 17:44:15 +0000 (10:44 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Aug 2011 20:04:42 +0000 (13:04 -0700)
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_wm.c

index 38b13098bc070a76d969d297cf8f2943f6960bdc..add8c5687952f72805c941edd4c4d6c47751d3a5 100644 (file)
@@ -312,6 +312,7 @@ struct brw_vs_prog_data {
    GLuint total_grf;
    GLbitfield64 outputs_written;
    GLuint nr_params;       /**< number of float params/constants */
+   GLuint total_scratch;
 
    GLuint inputs_read;
 
@@ -671,6 +672,7 @@ struct brw_context
       struct brw_vs_prog_data *prog_data;
       int8_t *constant_map; /* variable array following prog_data */
 
+      drm_intel_bo *scratch_bo;
       drm_intel_bo *const_bo;
       /** Offset in the program cache to the VS program */
       uint32_t prog_offset;
@@ -858,6 +860,10 @@ void brw_validate_textures( struct brw_context *brw );
  */
 void brwInitFragProgFuncs( struct dd_function_table *functions );
 
+int brw_get_scratch_size(int size);
+void brw_get_scratch_bo(struct intel_context *intel,
+                       drm_intel_bo **scratch_bo, int size);
+
 
 /* brw_urb.c
  */
index 6674f1640c83eb72cd680b40bfe7266925bb77be..09b5be4c96efd8b9834551201f74430bf0a90ea3 100644 (file)
@@ -226,6 +226,34 @@ static GLboolean brwProgramStringNotify( struct gl_context *ctx,
    return GL_TRUE;
 }
 
+/* Per-thread scratch space is a power-of-two multiple of 1KB. */
+int
+brw_get_scratch_size(int size)
+{
+   int i;
+
+   for (i = 1024; i < size; i *= 2)
+      ;
+
+   return i;
+}
+
+void
+brw_get_scratch_bo(struct intel_context *intel,
+                  drm_intel_bo **scratch_bo, int size)
+{
+   drm_intel_bo *old_bo = *scratch_bo;
+
+   if (old_bo && old_bo->size < size) {
+      drm_intel_bo_unreference(old_bo);
+      old_bo = NULL;
+   }
+
+   if (!old_bo) {
+      *scratch_bo = drm_intel_bo_alloc(intel->bufmgr, "scratch bo", size, 4096);
+   }
+}
+
 void brwInitFragProgFuncs( struct dd_function_table *functions )
 {
    assert(functions->ProgramStringNotify == _tnl_program_string); 
index bd0677db15168b72434eea78e5179707a9d47377..d389f602fba3b106e26d4aab3afb5492b200c6c8 100644 (file)
@@ -45,6 +45,7 @@ static void do_vs_prog( struct brw_context *brw,
                        struct brw_vs_prog_key *key )
 {
    struct gl_context *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;
    GLuint program_size;
    const GLuint *program;
    struct brw_vs_compile c;
@@ -97,6 +98,14 @@ static void do_vs_prog( struct brw_context *brw,
       brw_old_vs_emit(&c);
    }
 
+   /* Scratch space is used for register spilling */
+   if (c.last_scratch) {
+      c.prog_data.total_scratch = brw_get_scratch_size(c.last_scratch);
+
+      brw_get_scratch_bo(intel, &brw->vs.scratch_bo,
+                        c.prog_data.total_scratch * brw->vs_max_threads);
+   }
+
    /* get the program
     */
    program = brw_get_program(&c.func, &program_size);
index 9f9fed3397018f158fe39cbb0f42074d4618568d..83a37f5b800b7bfa84ef95e6b694028df1388ca7 100644 (file)
@@ -66,6 +66,7 @@ struct brw_vs_compile {
    GLuint first_output;
    GLuint nr_outputs;
    GLuint first_overflow_output; /**< VERT_ATTRIB_x */
+   GLuint last_scratch;
 
    GLuint first_tmp;
    GLuint last_tmp;
index d13ac6124c85b3392dcdcfcab135595909bd12af..a4524fc78899467923921ef23d61355e5fae0bda 100644 (file)
@@ -244,29 +244,10 @@ bool do_wm_prog(struct brw_context *brw,
 
    /* Scratch space is used for register spilling */
    if (c->last_scratch) {
-      uint32_t total_scratch;
+      c->prog_data.total_scratch = brw_get_scratch_size(c->last_scratch);
 
-      /* Per-thread scratch space is power-of-two sized. */
-      for (c->prog_data.total_scratch = 1024;
-          c->prog_data.total_scratch <= c->last_scratch;
-          c->prog_data.total_scratch *= 2) {
-        /* empty */
-      }
-      total_scratch = c->prog_data.total_scratch * brw->wm_max_threads;
-
-      if (brw->wm.scratch_bo && total_scratch > brw->wm.scratch_bo->size) {
-        drm_intel_bo_unreference(brw->wm.scratch_bo);
-        brw->wm.scratch_bo = NULL;
-      }
-      if (brw->wm.scratch_bo == NULL) {
-        brw->wm.scratch_bo = drm_intel_bo_alloc(intel->bufmgr,
-                                                "wm scratch",
-                                                total_scratch,
-                                                4096);
-      }
-   }
-   else {
-      c->prog_data.total_scratch = 0;
+      brw_get_scratch_bo(intel, &brw->vs.scratch_bo,
+                        c->prog_data.total_scratch * brw->wm_max_threads);
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_WM))