i965g: more work on compilation
authorKeith Whitwell <keithw@vmware.com>
Sat, 31 Oct 2009 20:05:19 +0000 (20:05 +0000)
committerKeith Whitwell <keithw@vmware.com>
Sat, 31 Oct 2009 20:05:19 +0000 (20:05 +0000)
src/gallium/auxiliary/util/u_math.h
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/i965/brw_pipe_sampler.c
src/gallium/drivers/i965/brw_structs.h
src/gallium/drivers/i965/brw_wm_sampler_state.c
src/gallium/drivers/i965/brw_wm_state.c

index 75b075f160d922c14c0277a57dd9c5b7b60ec680..c13bf96177da1ad94a38b75f082c1cfba77e6669 100644 (file)
@@ -539,6 +539,19 @@ do {                                     \
 #endif
 
 
+static INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits)
+{
+   value *= (1<<frac_bits);
+   return value < 0 ? 0 : value;
+}
+
+static INLINE int32_t util_signed_fixed(float value, unsigned frac_bits)
+{
+   return value * (1<<frac_bits);
+}
+
+
+
 #ifdef __cplusplus
 }
 #endif
index e6c31610669f641e760fb383b1ac9e6afb0da00b..8067e20c968eeab6cbd85d8f661843a656ad9b5e 100644 (file)
@@ -177,6 +177,14 @@ struct brw_fragment_shader {
 };
 
 
+struct brw_sampler {
+   struct pipe_sampler_state templ;
+   struct brw_ss0 ss0;
+   struct brw_ss1 ss1;
+   struct brw_ss3 ss3;
+};
+
+
 
 #define PIPE_NEW_DEPTH_STENCIL_ALPHA    0x1
 #define PIPE_NEW_RAST                   0x2
@@ -494,7 +502,7 @@ struct brw_context
       const struct brw_depth_stencil_state *zstencil;
 
       const struct brw_texture *texture[PIPE_MAX_SAMPLERS];
-      const struct pipe_sampler *sampler[PIPE_MAX_SAMPLERS];
+      const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
       unsigned num_textures;
       unsigned num_samplers;
       
index bc20eef6fb280a0e3ea8dfe03e7e7d6dc5d59302..08a5d220097b93d8fa71a315fcd5e66feb0d3938 100644 (file)
@@ -9,6 +9,38 @@
 
 
 
+/* The brw (and related graphics cores) do not support GL_CLAMP.  The
+ * Intel drivers for "other operating systems" implement GL_CLAMP as
+ * GL_CLAMP_TO_EDGE, so the same is done here.
+ */
+static GLuint translate_wrap_mode( unsigned wrap )
+{
+   switch( wrap ) {
+   case PIPE_TEX_WRAP_REPEAT: 
+      return BRW_TEXCOORDMODE_WRAP;
+
+   case PIPE_TEX_WRAP_CLAMP:
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+      return BRW_TEXCOORDMODE_CLAMP;
+      
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+      return BRW_TEXCOORDMODE_CLAMP_BORDER;
+
+   case PIPE_TEX_WRAP_MIRROR_REPEAT: 
+      return BRW_TEXCOORDMODE_MIRROR;
+
+   case PIPE_TEX_WRAP_MIRROR_CLAMP: 
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 
+      return BRW_TEXCOORDMODE_MIRROR_ONCE;
+
+   default: 
+      return BRW_TEXCOORDMODE_WRAP;
+   }
+}
+
+
+
 static void *brw_create_sampler_state( struct pipe_context *pipe,
                                     const struct pipe_sampler_state *templ )
 {
index 11372697f9bf2ab91ddf561b170487aa49b072e1..f5d6a2599b42b0e6c756fc70d5b47001565b1be5 100644 (file)
@@ -965,7 +965,7 @@ struct brw_sampler_default_color {
 struct brw_sampler_state
 {
    
-   struct
+   struct brw_ss0
    {
       GLuint shadow_function:3; 
       GLuint lod_bias:11; 
@@ -980,7 +980,7 @@ struct brw_sampler_state
       GLuint disable:1; 
    } ss0;
 
-   struct
+   struct brw_ss1
    {
       GLuint r_wrap_mode:3; 
       GLuint t_wrap_mode:3; 
@@ -991,13 +991,13 @@ struct brw_sampler_state
    } ss1;
 
    
-   struct
+   struct brw_ss2
    {
       GLuint pad:5;
       GLuint default_color_pointer:27; 
    } ss2;
    
-   struct
+   struct brw_ss3
    {
       GLuint pad:19;
       GLuint max_aniso:3; 
index 32692d533c4ebf896eeb3341cda9a1c57fc79fe9..55698a58bbc520d67a4486de1557e9cfb0f07788 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
                    
+#include "util/u_math.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
+#include "brw_screen.h"
 
 
 /* Samplers aren't strictly wm state from the hardware's perspective,
 
 
 
-/* The brw (and related graphics cores) do not support GL_CLAMP.  The
- * Intel drivers for "other operating systems" implement GL_CLAMP as
- * GL_CLAMP_TO_EDGE, so the same is done here.
- */
-static GLuint translate_wrap_mode( GLenum wrap )
-{
-   switch( wrap ) {
-   case GL_REPEAT: 
-      return BRW_TEXCOORDMODE_WRAP;
-   case GL_CLAMP:  
-      return BRW_TEXCOORDMODE_CLAMP;
-   case GL_CLAMP_TO_EDGE: 
-      return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */
-   case GL_CLAMP_TO_BORDER: 
-      return BRW_TEXCOORDMODE_CLAMP_BORDER;
-   case GL_MIRRORED_REPEAT: 
-      return BRW_TEXCOORDMODE_MIRROR;
-   default: 
-      return BRW_TEXCOORDMODE_WRAP;
-   }
-}
-
-
-static GLuint U_FIXED(GLfloat value, GLuint frac_bits)
-{
-   value *= (1<<frac_bits);
-   return value < 0 ? 0 : value;
-}
-
-static GLint S_FIXED(GLfloat value, GLuint frac_bits)
-{
-   return value * (1<<frac_bits);
-}
-
-
 static struct brw_winsys_buffer *
 upload_default_color( struct brw_context *brw,
                      const GLfloat *color )
@@ -91,91 +58,78 @@ upload_default_color( struct brw_context *brw,
 
 struct wm_sampler_key {
    int sampler_count;
-
-   struct wm_sampler_entry {
-      GLenum tex_target;
-      GLenum wrap_r, wrap_s, wrap_t;
-      float maxlod, minlod;
-      float lod_bias;
-      float max_aniso;
-      GLenum minfilter, magfilter;
-      GLenum comparemode, comparefunc;
-      struct brw_winsys_buffer *sdc_bo;
-
-      /** If target is cubemap, take context setting.
-       */
-      GLboolean seamless_cube_map;
-   } sampler[BRW_MAX_TEX_UNIT];
+   struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
 };
 
-/**
- * Sets the sampler state for a single unit based off of the sampler key
- * entry.
- */
-static void brw_update_sampler_state(struct wm_sampler_entry *key,
-                                    struct brw_winsys_buffer *sdc_bo,
-                                    struct brw_sampler_state *sampler)
-{
-   _mesa_memset(sampler, 0, sizeof(*sampler));
-
-   /* Cube-maps on 965 and later must use the same wrap mode for all 3
-    * coordinate dimensions.  Futher, only CUBE and CLAMP are valid.
-    */
-   if (key->tex_target == GL_TEXTURE_CUBE_MAP) {
-      if (key->seamless_cube_map &&
-         (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) {
-        sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
-        sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
-        sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
-      } else {
-        sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-        sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-        sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
-      }
-   } else if (key->tex_target == GL_TEXTURE_1D) {
-      /* There's a bug in 1D texture sampling - it actually pays
-       * attention to the wrap_t value, though it should not.
-       * Override the wrap_t value here to GL_REPEAT to keep
-       * any nonexistent border pixels from floating in.
-       */
-      sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
-   }
-
-
-
-   sampler->ss2.default_color_pointer = sdc_bo->offset >> 5; /* reloc */
-}
-
 
 /** Sets up the cache key for sampler state for all texture units */
 static void
 brw_wm_sampler_populate_key(struct brw_context *brw,
                            struct wm_sampler_key *key)
 {
-   int nr = MIN2(brw->curr.number_textures,
-                brw->curr.number_samplers);
    int i;
 
    memset(key, 0, sizeof(*key));
 
-   for (i = 0; i < nr; i++) {
+   key->sampler_count = MIN2(brw->curr.num_textures,
+                           brw->curr.num_samplers);
+
+   for (i = 0; i < key->sampler_count; i++) {
       const struct brw_texture *tex = brw->curr.texture[i];
       const struct brw_sampler *sampler = brw->curr.sampler[i];
-      struct wm_sampler_entry *entry = &key->sampler[i];
+      struct brw_sampler_state *entry = &key->sampler[i];
 
-      entry->tex_target = texObj->Target;
-      entry->seamless_cube_map = FALSE; /* XXX: add this to gallium */
       entry->ss0 = sampler->ss0;
       entry->ss1 = sampler->ss1;
+      entry->ss2.default_color_pointer = brw->wm.sdc_bo[i]->offset >> 5; /* reloc */
       entry->ss3 = sampler->ss3;
 
+      /* Cube-maps on 965 and later must use the same wrap mode for all 3
+       * coordinate dimensions.  Futher, only CUBE and CLAMP are valid.
+       */
+      if (tex->base.target == PIPE_TEXTURE_CUBE) {
+        if (FALSE &&
+            (sampler->ss0.min_filter != BRW_MAPFILTER_NEAREST || 
+             sampler->ss0.mag_filter != BRW_MAPFILTER_NEAREST)) {
+           entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+           entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+           entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+        } else {
+           entry->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+           entry->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+           entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+        }
+      } else if (tex->base.target == PIPE_TEXTURE_1D) {
+        /* There's a bug in 1D texture sampling - it actually pays
+         * attention to the wrap_t value, though it should not.
+         * Override the wrap_t value here to GL_REPEAT to keep
+         * any nonexistent border pixels from floating in.
+         */
+        entry->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
+      }
+   }
+}
+
+
+static void
+brw_wm_sampler_update_default_colors(struct brw_context *brw)
+{
+   int nr = MIN2(brw->curr.num_textures,
+                brw->curr.num_samplers);
+   int i;
+
+   for (i = 0; i < nr; i++) {
+      const struct brw_texture *tex = brw->curr.texture[i];
+      const struct brw_sampler *sampler = brw->curr.sampler[i];
+
       brw->sws->bo_unreference(brw->wm.sdc_bo[i]);
-      if (firstImage->_BaseFormat == GL_DEPTH_COMPONENT) {
+
+      if (pf_is_depth_or_stencil(tex->base.format)) {
         float bordercolor[4] = {
-           texObj->BorderColor[0],
-           texObj->BorderColor[0],
-           texObj->BorderColor[0],
-           texObj->BorderColor[0]
+           sampler->templ.border_color[0],
+           sampler->templ.border_color[0],
+           sampler->templ.border_color[0],
+           sampler->templ.border_color[0]
         };
         /* GL specs that border color for depth textures is taken from the
          * R channel, while the hardware uses A.  Spam R into all the
@@ -183,22 +137,21 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
          */
         brw->wm.sdc_bo[i] = upload_default_color(brw, bordercolor);
       } else {
-        brw->wm.sdc_bo[i] = upload_default_color(brw, texObj->BorderColor);
+        brw->wm.sdc_bo[i] = upload_default_color(brw, sampler->templ.border_color);
       }
    }
-
-   key->sampler_count = nr;
 }
 
-/* All samplers must be uploaded in a single contiguous array, which
- * complicates various things.  However, this is still too confusing -
- * FIXME: simplify all the different new texture state flags.
+
+
+/* All samplers must be uploaded in a single contiguous array.  
  */
-static void upload_wm_samplers( struct brw_context *brw )
+static int upload_wm_samplers( struct brw_context *brw )
 {
    struct wm_sampler_key key;
    int i;
 
+   brw_wm_sampler_update_default_colors(brw);
    brw_wm_sampler_populate_key(brw, &key);
 
    if (brw->wm.sampler_count != key.sampler_count) {
@@ -209,7 +162,7 @@ static void upload_wm_samplers( struct brw_context *brw )
    brw->sws->bo_unreference(brw->wm.sampler_bo);
    brw->wm.sampler_bo = NULL;
    if (brw->wm.sampler_count == 0)
-      return;
+      return 0;
 
    brw->wm.sampler_bo = brw_search_cache(&brw->cache, BRW_SAMPLER,
                                         &key, sizeof(key),
@@ -220,41 +173,29 @@ static void upload_wm_samplers( struct brw_context *brw )
     * cache.
     */
    if (brw->wm.sampler_bo == NULL) {
-      struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
-
-      memset(sampler, 0, sizeof(sampler));
-      for (i = 0; i < key.sampler_count; i++) {
-        if (brw->wm.sdc_bo[i] == NULL)
-           continue;
-
-        brw_update_sampler_state(&key.sampler[i], brw->wm.sdc_bo[i],
-                                 &sampler[i]);
-      }
-
       brw->wm.sampler_bo = brw_upload_cache(&brw->cache, BRW_SAMPLER,
                                            &key, sizeof(key),
                                            brw->wm.sdc_bo, key.sampler_count,
-                                           &sampler, sizeof(sampler),
+                                           &key.sampler, sizeof(key.sampler),
                                            NULL, NULL);
 
       /* Emit SDC relocations */
-      for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
-        if (!ctx->Texture.Unit[i]._ReallyEnabled)
-           continue;
-
-        dri_bo_emit_reloc(brw->wm.sampler_bo,
-                          I915_GEM_DOMAIN_SAMPLER, 0,
-                          0,
-                          i * sizeof(struct brw_sampler_state) +
-                          offsetof(struct brw_sampler_state, ss2),
-                          brw->wm.sdc_bo[i]);
+      for (i = 0; i < key.sampler_count; i++) {
+        brw->sws->bo_emit_reloc(brw->wm.sampler_bo,
+                                I915_GEM_DOMAIN_SAMPLER, 0,
+                                0,
+                                i * sizeof(struct brw_sampler_state) +
+                                offsetof(struct brw_sampler_state, ss2),
+                                brw->wm.sdc_bo[i]);
       }
    }
+
+   return 0;
 }
 
 const struct brw_tracked_state brw_wm_samplers = {
    .dirty = {
-      .mesa = PIPE_NEW_BOUND_TEXTURES | PIPE_NEW_SAMPLER,
+      .mesa = PIPE_NEW_BOUND_TEXTURES | PIPE_NEW_SAMPLERS,
       .brw = 0,
       .cache = 0
    },
index 1898f38cef1217aabeacd328ed6976fb466d4738..f161de9b4013050fd537f80e01c0d59573249367 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
                    
-
+#include "util/u_math.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
 #include "brw_defines.h"
 #include "brw_wm.h"
+#include "brw_debug.h"
+#include "brw_pipe_rast.h"
 
 /***********************************************************************
  * WM unit - fragment programs and rasterization
@@ -60,8 +62,7 @@ struct brw_wm_unit_key {
 static void
 wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
 {
-   const struct gl_fragment_program *fp = brw->fragment_program;
-   const struct brw_fragment_program *bfp = (struct brw_fragment_program *) fp;
+   const struct brw_fragment_shader *fp = brw->curr.fragment_shader;
 
    memset(key, 0, sizeof(*key));
 
@@ -82,7 +83,7 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
    key->urb_entry_read_length = brw->wm.prog_data->urb_read_length;
    key->curb_entry_read_length = brw->wm.prog_data->curb_read_length;
    key->dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf;
-   key->total_scratch = ALIGN(brw->wm.prog_data->total_scratch, 1024);
+   key->total_scratch = align(brw->wm.prog_data->total_scratch, 1024);
 
    /* BRW_NEW_URB_FENCE */
    key->urb_size = brw->urb.vsize;
@@ -96,39 +97,42 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
    /* CACHE_NEW_SAMPLER */
    key->sampler_count = brw->wm.sampler_count;
 
-   /* _NEW_POLYGONSTIPPLE */
-   key->polygon_stipple = ctx->Polygon.StippleFlag;
+   /* PIPE_NEW_RAST */
+   key->polygon_stipple = brw->curr.rast->templ.poly_stipple_enable;
 
-   /* BRW_NEW_FRAGMENT_PROGRAM */
-   key->uses_depth = (fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
+   /* PIPE_NEW_FRAGMENT_PROGRAM */
+   key->uses_depth = fp->uses_depth;
+   key->computes_depth = fp->info.writes_z;
 
-   /* as far as we can tell */
-   key->computes_depth =
-      (fp->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) != 0;
    /* PIPE_NEW_DEPTH_BUFFER
+    *
     * Override for NULL depthbuffer case, required by the Pixel Shader Computed
     * Depth field.
     */
    if (brw->curr.fb.zsbuf == NULL)
       key->computes_depth = 0;
 
-   /* _NEW_COLOR */
-   key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
-   key->has_flow_control = bfp->has_flow_control;
+   /* PIPE_NEW_DEPTH_STENCIL_ALPHA */
+   key->uses_kill = (fp->info.uses_kill || 
+                    brw->curr.zstencil->cc3.alpha_test);
+
+   key->has_flow_control = fp->has_flow_control;
 
    /* temporary sanity check assertion */
-   ASSERT(bfp->has_flow_control == brw_wm_has_flow_control(fp));
+   assert(fp->has_flow_control == 0);
 
-   /* _NEW_QUERY */
+   /* PIPE_NEW_QUERY */
    key->stats_wm = (brw->query.stats_wm != 0);
 
-   /* _NEW_LINE */
-   key->line_stipple = ctx->Line.StippleFlag;
+   /* PIPE_NEW_RAST */
+   key->line_stipple = brw->curr.rast->templ.line_stipple_enable;
+
 
-   /* _NEW_POLYGON */
-   key->offset_enable = ctx->Polygon.OffsetFill;
-   key->offset_units = ctx->Polygon.OffsetUnits;
-   key->offset_factor = ctx->Polygon.OffsetFactor;
+   key->offset_enable = (brw->curr.rast->templ.offset_cw ||
+                        brw->curr.rast->templ.offset_ccw);
+
+   key->offset_units = brw->curr.rast->templ.offset_units;
+   key->offset_factor = brw->curr.rast->templ.offset_scale;
 }
 
 /**
@@ -143,7 +147,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
 
    memset(&wm, 0, sizeof(wm));
 
-   wm.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1;
+   wm.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
    wm.thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
    wm.thread1.depth_coef_urb_read_offset = 1;
    wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
@@ -225,7 +229,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
                         NULL, NULL);
 
    /* Emit WM program relocation */
-   dri_bo_emit_reloc(bo,
+   brw->sws->bo_emit_reloc(bo,
                     I915_GEM_DOMAIN_INSTRUCTION, 0,
                     wm.thread0.grf_reg_count << 1,
                     offsetof(struct brw_wm_unit_state, thread0),
@@ -233,7 +237,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
 
    /* Emit scratch space relocation */
    if (key->total_scratch != 0) {
-      dri_bo_emit_reloc(bo,
+      brw->sws->bo_emit_reloc(bo,
                        0, 0,
                        wm.thread2.per_thread_scratch_space,
                        offsetof(struct brw_wm_unit_state, thread2),
@@ -242,7 +246,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
 
    /* Emit sampler state relocation */
    if (key->sampler_count != 0) {
-      dri_bo_emit_reloc(bo,
+      brw->sws->bo_emit_reloc(bo,
                        I915_GEM_DOMAIN_INSTRUCTION, 0,
                        wm.wm4.stats_enable | (wm.wm4.sampler_count << 2),
                        offsetof(struct brw_wm_unit_state, wm4),
@@ -253,7 +257,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
 }
 
 
-static void upload_wm_unit( struct brw_context *brw )
+static int upload_wm_unit( struct brw_context *brw )
 {
    struct brw_wm_unit_key key;
    struct brw_winsys_buffer *reloc_bufs[3];
@@ -291,19 +295,19 @@ static void upload_wm_unit( struct brw_context *brw )
    if (brw->wm.state_bo == NULL) {
       brw->wm.state_bo = wm_unit_create_from_key(brw, &key, reloc_bufs);
    }
+
+   return 0;
 }
 
 const struct brw_tracked_state brw_wm_unit = {
    .dirty = {
-      .mesa = (PIPE_NEW_DEPTH_BUFFER |
-              _NEW_POLYGON | 
-              _NEW_POLYGONSTIPPLE | 
-              _NEW_LINE | 
-              _NEW_COLOR |
-              _NEW_QUERY),
-
-      .brw = (BRW_NEW_FRAGMENT_PROGRAM | 
-             BRW_NEW_CURBE_OFFSETS |
+      .mesa = (PIPE_NEW_FRAGMENT_SHADER |
+              PIPE_NEW_DEPTH_BUFFER |
+              PIPE_NEW_RAST | 
+              PIPE_NEW_DEPTH_STENCIL_ALPHA |
+              PIPE_NEW_QUERY),
+
+      .brw = (BRW_NEW_CURBE_OFFSETS |
              BRW_NEW_NR_WM_SURFACES),
 
       .cache = (CACHE_NEW_WM_PROG |