i965: Split constant buffer setup from its surface state/binding state.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_surface_state.c
index 357c8c90de3d23e5b19f37968a92ff3087cba453..2b216fddbb5369885116af1f24f1b35addff4012 100644 (file)
@@ -196,44 +196,25 @@ brw_set_surface_tiling(struct brw_surface_state *surf, uint32_t tiling)
    }
 }
 
-static dri_bo *
+static drm_intel_bo *
 brw_create_texture_surface( struct brw_context *brw,
                            struct brw_surface_key *key )
 {
    struct brw_surface_state surf;
-   dri_bo *bo;
+   drm_intel_bo *bo;
 
    memset(&surf, 0, sizeof(surf));
 
    surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
    surf.ss0.surface_type = translate_tex_target(key->target);
-   if (key->bo) {
-      surf.ss0.surface_format = translate_tex_format(key->format,
-                                                    key->internal_format,
-                                                    key->depthmode);
-   }
-   else {
-      switch (key->depth) {
-      case 32:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
-         break;
-      default:
-      case 24:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
-         break;
-      case 16:
-         surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
-         break;
-      }
-   }
+   surf.ss0.surface_format = translate_tex_format(key->format,
+                                                 key->internal_format,
+                                                 key->depthmode);
 
    /* This is ok for all textures with channel width 8bit or less:
     */
 /*    surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-   if (key->bo)
-      surf.ss1.base_addr = key->bo->offset; /* reloc */
-   else
-      surf.ss1.base_addr = key->offset;
+   surf.ss1.base_addr = key->bo->offset; /* reloc */
 
    surf.ss2.mip_count = key->last_level - key->first_level;
    surf.ss2.width = key->width - 1;
@@ -255,17 +236,14 @@ brw_create_texture_surface( struct brw_context *brw,
 
    bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
                         key, sizeof(*key),
-                        &key->bo, key->bo ? 1 : 0,
+                        &key->bo, 1,
                         &surf, sizeof(surf));
 
-   if (key->bo) {
-      /* Emit relocation to surface contents */
-      dri_bo_emit_reloc(bo,
-                       I915_GEM_DOMAIN_SAMPLER, 0,
-                       0,
-                       offsetof(struct brw_surface_state, ss1),
-                       key->bo);
-   }
+   /* Emit relocation to surface contents */
+   drm_intel_bo_emit_reloc(bo, offsetof(struct brw_surface_state, ss1),
+                          key->bo, 0,
+                          I915_GEM_DOMAIN_SAMPLER, 0);
+
    return bo;
 }
 
@@ -281,19 +259,12 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
 
    memset(&key, 0, sizeof(key));
 
-   if (intelObj->imageOverride) {
-      key.pitch = intelObj->pitchOverride / intelObj->mt->cpp;
-      key.depth = intelObj->depthOverride;
-      key.bo = NULL;
-      key.offset = intelObj->textureOffset;
-   } else {
-      key.format = firstImage->TexFormat;
-      key.internal_format = firstImage->InternalFormat;
-      key.pitch = intelObj->mt->pitch;
-      key.depth = firstImage->Depth;
-      key.bo = intelObj->mt->region->buffer;
-      key.offset = 0;
-   }
+   key.format = firstImage->TexFormat;
+   key.internal_format = firstImage->InternalFormat;
+   key.pitch = intelObj->mt->region->pitch;
+   key.depth = firstImage->Depth;
+   key.bo = intelObj->mt->region->buffer;
+   key.offset = 0;
 
    key.target = tObj->Target;
    key.depthmode = tObj->DepthMode;
@@ -304,11 +275,11 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
    key.cpp = intelObj->mt->cpp;
    key.tiling = intelObj->mt->region->tiling;
 
-   dri_bo_unreference(brw->wm.surf_bo[surf]);
+   drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
    brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
                                             BRW_SS_SURFACE,
                                             &key, sizeof(key),
-                                            &key.bo, key.bo ? 1 : 0,
+                                            &key.bo, 1,
                                             NULL);
    if (brw->wm.surf_bo[surf] == NULL) {
       brw->wm.surf_bo[surf] = brw_create_texture_surface(brw, &key);
@@ -321,13 +292,13 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
  * Create the constant buffer surface.  Vertex/fragment shader constants will be
  * read from this buffer with Data Port Read instructions/messages.
  */
-dri_bo *
+drm_intel_bo *
 brw_create_constant_surface( struct brw_context *brw,
                              struct brw_surface_key *key )
 {
    const GLint w = key->width - 1;
    struct brw_surface_state surf;
-   dri_bo *bo;
+   drm_intel_bo *bo;
 
    memset(&surf, 0, sizeof(surf));
 
@@ -336,10 +307,7 @@ brw_create_constant_surface( struct brw_context *brw,
    surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
 
    assert(key->bo);
-   if (key->bo)
-      surf.ss1.base_addr = key->bo->offset; /* reloc */
-   else
-      surf.ss1.base_addr = key->offset;
+   surf.ss1.base_addr = key->bo->offset; /* reloc */
 
    surf.ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
    surf.ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
@@ -349,20 +317,16 @@ brw_create_constant_surface( struct brw_context *brw,
  
    bo = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
                         key, sizeof(*key),
-                        &key->bo, key->bo ? 1 : 0,
+                        &key->bo, 1,
                         &surf, sizeof(surf));
 
-   if (key->bo) {
-      /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
-       * bspec ("Data Cache") says that the data cache does not exist as
-       * a separate cache and is just the sampler cache.
-       */
-      dri_bo_emit_reloc(bo,
-                       I915_GEM_DOMAIN_SAMPLER, 0,
-                       0,
-                       offsetof(struct brw_surface_state, ss1),
-                       key->bo);
-   }
+   /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
+    * bspec ("Data Cache") says that the data cache does not exist as
+    * a separate cache and is just the sampler cache.
+    */
+   drm_intel_bo_emit_reloc(bo, offsetof(struct brw_surface_state, ss1),
+                          key->bo, 0,
+                          I915_GEM_DOMAIN_SAMPLER, 0);
 
    return bo;
 }
@@ -373,29 +337,45 @@ brw_create_constant_surface( struct brw_context *brw,
  * Otherwise, constants go through the CURBEs using the brw_constant_buffer
  * state atom.
  */
-static drm_intel_bo *
-brw_wm_update_constant_buffer(struct brw_context *brw)
+static void
+prepare_wm_constants(struct brw_context *brw)
 {
+   GLcontext *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
    struct brw_fragment_program *fp =
       (struct brw_fragment_program *) brw->fragment_program;
    const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
    const int size = params->NumParameters * 4 * sizeof(GLfloat);
-   drm_intel_bo *const_buffer;
+
+   _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
 
    /* BRW_NEW_FRAGMENT_PROGRAM */
-   if (!fp->use_const_buffer)
-      return NULL;
+   if (!fp->use_const_buffer) {
+      if (brw->wm.const_bo) {
+        drm_intel_bo_unreference(brw->wm.const_bo);
+        brw->wm.const_bo = NULL;
+        brw->state.dirty.brw |= BRW_NEW_WM_CONSTBUF;
+      }
+      return;
+   }
 
-   const_buffer = drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer",
-                                    size, 64);
+   drm_intel_bo_unreference(brw->wm.const_bo);
+   brw->wm.const_bo = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
+                                        size, 64);
 
    /* _NEW_PROGRAM_CONSTANTS */
-   dri_bo_subdata(const_buffer, 0, size, params->ParameterValues);
-
-   return const_buffer;
+   drm_intel_bo_subdata(brw->wm.const_bo, 0, size, params->ParameterValues);
 }
 
+const struct brw_tracked_state brw_wm_constants = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM_CONSTANTS),
+      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+      .cache = 0
+   },
+   .prepare = prepare_wm_constants,
+};
+
 /**
  * Update the surface state for a WM constant buffer.
  * The constant buffer will be (re)allocated here if needed.
@@ -411,16 +391,10 @@ brw_update_wm_constant_surface( GLcontext *ctx,
    const struct gl_program_parameter_list *params =
       fp->program.Base.Parameters;
 
-   /* If we're in this state update atom, we need to update WM constants, so
-    * free the old buffer and create a new one for the new contents.
-    */
-   dri_bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
    /* If there's no constant buffer, then no surface BO is needed to point at
     * it.
     */
-   if (fp->const_buffer == 0) {
+   if (brw->wm.const_bo == NULL) {
       drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
       brw->wm.surf_bo[surf] = NULL;
       return;
@@ -430,7 +404,7 @@ brw_update_wm_constant_surface( GLcontext *ctx,
 
    key.format = MESA_FORMAT_RGBA_FLOAT32;
    key.internal_format = GL_RGBA;
-   key.bo = fp->const_buffer;
+   key.bo = brw->wm.const_bo;
    key.depthmode = GL_NONE;
    key.pitch = params->NumParameters;
    key.width = params->NumParameters;
@@ -444,11 +418,11 @@ brw_update_wm_constant_surface( GLcontext *ctx,
           key.width, key.height, key.depth, key.cpp, key.pitch);
    */
 
-   dri_bo_unreference(brw->wm.surf_bo[surf]);
+   drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
    brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
                                             BRW_SS_SURFACE,
                                             &key, sizeof(key),
-                                            &key.bo, key.bo ? 1 : 0,
+                                            &key.bo, 1,
                                             NULL);
    if (brw->wm.surf_bo[surf] == NULL) {
       brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
@@ -467,17 +441,12 @@ brw_update_wm_constant_surface( GLcontext *ctx,
 static void prepare_wm_constant_surface(struct brw_context *brw )
 {
    GLcontext *ctx = &brw->intel.ctx;
-   struct brw_fragment_program *fp =
-      (struct brw_fragment_program *) brw->fragment_program;
    GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
 
-   drm_intel_bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
    /* If there's no constant buffer, then no surface BO is needed to point at
     * it.
     */
-   if (fp->const_buffer == 0) {
+   if (brw->wm.const_bo == 0) {
       if (brw->wm.surf_bo[surf] != NULL) {
         drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
         brw->wm.surf_bo[surf] = NULL;
@@ -491,8 +460,8 @@ static void prepare_wm_constant_surface(struct brw_context *brw )
 
 const struct brw_tracked_state brw_wm_constant_surface = {
    .dirty = {
-      .mesa = (_NEW_PROGRAM_CONSTANTS),
-      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+      .mesa = 0,
+      .brw = (BRW_NEW_WM_CONSTBUF),
       .cache = 0
    },
    .prepare = prepare_wm_constant_surface,
@@ -509,9 +478,9 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
                                struct gl_renderbuffer *rb,
                                unsigned int unit)
 {
-   struct intel_context *intel = &brw->intel;;
+   struct intel_context *intel = &brw->intel;
    GLcontext *ctx = &intel->ctx;
-   dri_bo *region_bo = NULL;
+   drm_intel_bo *region_bo = NULL;
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
    struct intel_region *region = irb ? irb->region : NULL;
    struct {
@@ -551,17 +520,15 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       case MESA_FORMAT_ARGB4444:
         key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
         break;
+      case MESA_FORMAT_A8:
+        key.surface_format = BRW_SURFACEFORMAT_A8_UNORM;
+        break;
       default:
         _mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
       }
       key.tiling = region->tiling;
-      if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
-        key.width = rb->Width;
-        key.height = rb->Height;
-      } else {
-        key.width = region->width;
-        key.height = region->height;
-      }
+      key.width = rb->Width;
+      key.height = rb->Height;
       key.pitch = region->pitch;
       key.cpp = region->cpp;
       key.draw_x = region->draw_x;
@@ -576,20 +543,23 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       key.draw_x = 0;
       key.draw_y = 0;
    }
-   /* _NEW_COLOR */
-   memcpy(key.color_mask, ctx->Color.ColorMask[0],
-         sizeof(key.color_mask));
 
-   /* As mentioned above, disable writes to the alpha component when the
-    * renderbuffer is XRGB.
-    */
-   if (ctx->DrawBuffer->Visual.alphaBits == 0)
-     key.color_mask[3] = GL_FALSE;
+   if (intel->gen < 6) {
+      /* _NEW_COLOR */
+      memcpy(key.color_mask, ctx->Color.ColorMask[unit],
+            sizeof(key.color_mask));
 
-   key.color_blend = (!ctx->Color._LogicOpEnabled &&
-                     ctx->Color.BlendEnabled);
+      /* As mentioned above, disable writes to the alpha component when the
+       * renderbuffer is XRGB.
+       */
+      if (ctx->DrawBuffer->Visual.alphaBits == 0)
+        key.color_mask[3] = GL_FALSE;
 
-   dri_bo_unreference(brw->wm.surf_bo[unit]);
+      key.color_blend = (!ctx->Color._LogicOpEnabled &&
+                        (ctx->Color.BlendEnabled & (1 << unit)));
+   }
+
+   drm_intel_bo_unreference(brw->wm.surf_bo[unit]);
    brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
                                            BRW_SS_SURFACE,
                                            &key, sizeof(key),
@@ -621,7 +591,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
            tile_base = ((key.draw_y / 32) * (32 * pitch));
            tile_base += (key.draw_x - tile_x) / (128 / key.cpp) * 4096;
         }
-        assert(intel->is_g4x || (tile_x == 0 && tile_y == 0));
+        assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
         assert(tile_x % 4 == 0);
         assert(tile_y % 2 == 0);
         /* Note that the low bits of these fields are missing, so
@@ -639,12 +609,14 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
       brw_set_surface_tiling(&surf, key.tiling);
       surf.ss3.pitch = (key.pitch * key.cpp) - 1;
 
-      /* _NEW_COLOR */
-      surf.ss0.color_blend = key.color_blend;
-      surf.ss0.writedisable_red =   !key.color_mask[0];
-      surf.ss0.writedisable_green = !key.color_mask[1];
-      surf.ss0.writedisable_blue =  !key.color_mask[2];
-      surf.ss0.writedisable_alpha = !key.color_mask[3];
+      if (intel->gen < 6) {
+        /* _NEW_COLOR */
+        surf.ss0.color_blend = key.color_blend;
+        surf.ss0.writedisable_red =   !key.color_mask[0];
+        surf.ss0.writedisable_green = !key.color_mask[1];
+        surf.ss0.writedisable_blue =  !key.color_mask[2];
+        surf.ss0.writedisable_alpha = !key.color_mask[3];
+      }
 
       /* Key size will never match key size for textures, so we're safe. */
       brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
@@ -672,10 +644,10 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
  * Constructs the binding table for the WM surface state, which maps unit
  * numbers to surface state objects.
  */
-static dri_bo *
+static drm_intel_bo *
 brw_wm_get_binding_table(struct brw_context *brw)
 {
-   dri_bo *bind_bo;
+   drm_intel_bo *bind_bo;
 
    assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
 
@@ -703,11 +675,9 @@ brw_wm_get_binding_table(struct brw_context *brw)
       /* Emit binding table relocations to surface state */
       for (i = 0; i < BRW_WM_MAX_SURF; i++) {
         if (brw->wm.surf_bo[i] != NULL) {
-           dri_bo_emit_reloc(bind_bo,
-                             I915_GEM_DOMAIN_INSTRUCTION, 0,
-                             0,
-                             i * sizeof(GLuint),
-                             brw->wm.surf_bo[i]);
+           drm_intel_bo_emit_reloc(bind_bo, i * sizeof(GLuint),
+                                   brw->wm.surf_bo[i], 0,
+                                   I915_GEM_DOMAIN_INSTRUCTION, 0);
         }
       }
    }
@@ -749,12 +719,12 @@ static void prepare_wm_surfaces(struct brw_context *brw )
         brw_update_texture_surface(ctx, i);
         brw->wm.nr_surfaces = surf + 1;
       } else {
-         dri_bo_unreference(brw->wm.surf_bo[surf]);
+         drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
          brw->wm.surf_bo[surf] = NULL;
       }
    }
 
-   dri_bo_unreference(brw->wm.bind_bo);
+   drm_intel_bo_unreference(brw->wm.bind_bo);
    brw->wm.bind_bo = brw_wm_get_binding_table(brw);
 
    if (brw->wm.nr_surfaces != old_nr_surfaces)