Merge branch '7.8'
[mesa.git] / src / gallium / drivers / i965 / brw_wm_surface_state.c
index e5d03299677c03a0a709f3e9d9f8c2366d5c3f59..2368ae3f808947cdd2d3f77a291a218551e9e082 100644 (file)
@@ -34,7 +34,6 @@
 #include "brw_batchbuffer.h"
 #include "brw_context.h"
 #include "brw_state.h"
-#include "brw_defines.h"
 #include "brw_screen.h"
 
 
@@ -45,33 +44,32 @@ brw_update_texture_surface( struct brw_context *brw,
                            struct brw_texture *tex,
                             struct brw_winsys_buffer **bo_out)
 {
+   struct brw_winsys_reloc reloc[1];
    enum pipe_error ret;
 
+   /* Emit relocation to surface contents */
+   make_reloc(&reloc[0],
+              BRW_USAGE_SAMPLER,
+              0,
+              offsetof(struct brw_surface_state, ss1),
+              tex->bo);
+
    if (brw_search_cache(&brw->surface_cache,
                         BRW_SS_SURFACE,
                         &tex->ss, sizeof tex->ss,
-                        &tex->bo, 1,
+                        reloc, Elements(reloc),
                         NULL,
                         bo_out))
       return PIPE_OK;
 
    ret = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
                           &tex->ss, sizeof tex->ss,
-                          &tex->bo, 1,
+                          reloc, Elements(reloc),
                           &tex->ss, sizeof tex->ss,
                           NULL, NULL,
                           bo_out);
    if (ret)
       return ret;
-      
-   /* Emit relocation to surface contents */
-   ret = brw->sws->bo_emit_reloc(*bo_out,
-                                 BRW_USAGE_SAMPLER,
-                                 0,
-                                 offsetof(struct brw_surface_state, ss1),
-                                 tex->bo);
-   if (ret)
-      return ret;
 
    return PIPE_OK;
 }
@@ -95,8 +93,17 @@ brw_update_render_surface(struct brw_context *brw,
 {
    struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
    struct brw_surface_state ss;
+   struct brw_winsys_reloc reloc[1];
    enum pipe_error ret;
 
+   /* XXX: we will only be rendering to this surface:
+    */
+   make_reloc(&reloc[0],
+              BRW_USAGE_RENDER_TARGET,
+              0,
+              offsetof(struct brw_surface_state, ss1),
+              surface->bo);
+
    /* Surfaces are potentially shared between contexts, so can't
     * scribble the in-place ss0 value in the surface.
     */
@@ -111,7 +118,7 @@ brw_update_render_surface(struct brw_context *brw,
    if (brw_search_cache(&brw->surface_cache,
                         BRW_SS_SURFACE,
                         &ss, sizeof(ss),
-                        &surface->bo, 1,
+                        reloc, Elements(reloc),
                         NULL,
                         bo_out))
       return PIPE_OK;
@@ -119,23 +126,13 @@ brw_update_render_surface(struct brw_context *brw,
    ret = brw_upload_cache(&brw->surface_cache,
                           BRW_SS_SURFACE,
                           &ss, sizeof ss,
-                          &surface->bo, 1,
+                          reloc, Elements(reloc),
                           &ss, sizeof ss,
                           NULL, NULL,
                           bo_out);
    if (ret)
       return ret;
 
-      /* XXX: we will only be rendering to this surface:
-       */
-   ret = brw->sws->bo_emit_reloc(*bo_out,
-                                 BRW_USAGE_RENDER_TARGET,
-                                 ss.ss1.base_addr - surface->bo->offset[0], /* XXX */
-                                 offsetof(struct brw_surface_state, ss1),
-                                 surface->bo);
-   if (ret)
-      return ret;
-
    return PIPE_OK;
 }
 
@@ -149,47 +146,52 @@ brw_wm_get_binding_table(struct brw_context *brw,
                          struct brw_winsys_buffer **bo_out )
 {
    enum pipe_error ret;
+   struct brw_winsys_reloc reloc[BRW_WM_MAX_SURF];
    uint32_t data[BRW_WM_MAX_SURF];
+   GLuint nr_relocs = 0;
    GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
    int i;
 
    assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
    assert(brw->wm.nr_surfaces > 0);
 
+   /* Emit binding table relocations to surface state 
+    */
+   for (i = 0; i < brw->wm.nr_surfaces; i++) {
+      if (brw->wm.surf_bo[i]) {
+         make_reloc(&reloc[nr_relocs++],
+                    BRW_USAGE_STATE,
+                    0,
+                    i * sizeof(GLuint),
+                    brw->wm.surf_bo[i]);
+      }
+   }
+
    /* Note there is no key for this search beyond the values in the
     * relocation array:
     */
    if (brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
                         NULL, 0,
-                        brw->wm.surf_bo,
-                        brw->wm.nr_surfaces,
+                        reloc, nr_relocs,
                         NULL,
                         bo_out))
       return PIPE_OK;
 
+   /* Upload zero data, will all be overwitten with relocation
+    * offsets:
+    */
    for (i = 0; i < brw->wm.nr_surfaces; i++)
-      data[i] = brw->wm.surf_bo[i]->offset[0];
+      data[i] = 0;
 
    ret = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
                            NULL, 0,
-                           brw->wm.surf_bo, brw->wm.nr_surfaces,
+                           reloc, nr_relocs,
                            data, data_size,
                            NULL, NULL,
                            bo_out);
    if (ret)
       return ret;
 
-   /* Emit binding table relocations to surface state */
-   for (i = 0; i < brw->wm.nr_surfaces; i++) {
-      ret = brw->sws->bo_emit_reloc(*bo_out,
-                                    BRW_USAGE_STATE,
-                                    0,
-                                    i * sizeof(GLuint),
-                                    brw->wm.surf_bo[i]);
-      if (ret)
-         return ret;
-   }
-
    return PIPE_OK;
 }
 
@@ -209,40 +211,60 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
    for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
       ret = brw_update_render_surface(brw, 
                                       brw_surface(brw->curr.fb.cbufs[i]), 
-                                      &brw->wm.surf_bo[nr_surfaces++]);
+                                      &brw->wm.surf_bo[BTI_COLOR_BUF(i)]);
       if (ret)
          return ret;
+      
+      nr_surfaces = BTI_COLOR_BUF(i) + 1;
    }
 
-   /* PIPE_NEW_TEXTURE 
-    */
-   for (i = 0; i < brw->curr.num_textures; i++) {
-      ret = brw_update_texture_surface(brw, 
-                                       brw_texture(brw->curr.texture[i]),
-                                       &brw->wm.surf_bo[nr_surfaces++]);
-      if (ret)
-         return ret;
-   }
+
 
    /* PIPE_NEW_FRAGMENT_CONSTANTS
     */
 #if 0
    if (brw->curr.fragment_constants) {
-      ret = brw_update_fragment_constant_surface(brw, 
-                                                 brw->curr.fragment_constants, 
-                                                 &brw->wm.surf_bo[nr_surfaces++]);
+      ret = brw_update_fragment_constant_surface(
+         brw, 
+         brw->curr.fragment_constants, 
+         &brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS]);
+
       if (ret)
          return ret;
+
+      nr_surfaces = BTI_FRAGMENT_CONSTANTS + 1;
+   }
+   else {
+      bo_reference(&brw->wm.surf_bo[SURF_FRAG_CONSTANTS], NULL);      
    }
 #endif
 
-   if (brw->wm.nr_surfaces != nr_surfaces) {
 
-      /* Unreference any left-over old buffers
-       */
-      for (i = nr_surfaces; i < brw->wm.nr_surfaces; i++)
-         bo_reference(&brw->wm.surf_bo[i], NULL);
+   /* PIPE_NEW_TEXTURE 
+    */
+   for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
+      ret = brw_update_texture_surface(brw, 
+                                       brw_texture(brw->curr.fragment_sampler_views[i]->texture),
+                                       &brw->wm.surf_bo[BTI_TEXTURE(i)]);
+      if (ret)
+         return ret;
+
+      nr_surfaces = BTI_TEXTURE(i) + 1;
+   }
 
+   /* Clear any inactive entries:
+    */
+   for (i = brw->curr.fb.nr_cbufs; i < BRW_MAX_DRAW_BUFFERS; i++) 
+      bo_reference(&brw->wm.surf_bo[BTI_COLOR_BUF(i)], NULL);
+
+   if (!brw->curr.fragment_constants)
+      bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);      
+
+   /* XXX: no pipe_max_textures define?? */
+   for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++)
+      bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
+
+   if (brw->wm.nr_surfaces != nr_surfaces) {
       brw->wm.nr_surfaces = nr_surfaces;
       brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
    }