iris: assemble SAMPLER_STATE table at bind time
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 7 Apr 2018 07:49:12 +0000 (00:49 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:05 +0000 (10:26 -0800)
It's useless to allocate SAMPLER_STATEs in GPU memory on creation like
we do for SURFACE_STATES, because they need to be organized into a
contiguous block of memory.  But we can do that at bind time, rather
than draw time.

src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_state.c

index 51eabf91e4b64700a75fafa6b95d3da7985eee3d..21e81d374776c9be5a7c0c714780cce8eb431e67 100644 (file)
@@ -183,10 +183,15 @@ struct iris_context {
       struct pipe_stencil_ref stencil_ref;
       struct pipe_framebuffer_state framebuffer;
 
+      struct pipe_resource *sampler_table_resource[MESA_SHADER_STAGES];
+      uint32_t sampler_table_offset[MESA_SHADER_STAGES];
       struct iris_sampler_state *samplers[MESA_SHADER_STAGES][IRIS_MAX_TEXTURE_SAMPLERS];
+      unsigned num_samplers;
 
       struct iris_binder binder;
       struct u_upload_mgr *surface_uploader;
+      // XXX: may want a separate uploader for "hey I made a CSO!" vs
+      // "I'm streaming this out at draw time and never want it again!"
       struct u_upload_mgr *dynamic_uploader;
 
       void (*destroy_state)(struct iris_context *ice);
index 20b2c29abbc8353a8368cfd203a557abfd30a929..a0f6a685b435ce1cc7b689015b60e735a04d439c 100644 (file)
@@ -872,10 +872,37 @@ iris_bind_sampler_states(struct pipe_context *ctx,
 
    assert(start + count <= IRIS_MAX_TEXTURE_SAMPLERS);
 
+   /* Assemble the SAMPLER_STATEs into a contiguous chunk of memory
+    * relative to Dynamic State Base Address.
+    */
+   void *map = NULL;
+   u_upload_alloc(ice->state.dynamic_uploader, 0,
+                  count * 4 * GENX(SAMPLER_STATE_length), 32,
+                  &ice->state.sampler_table_offset[stage],
+                  &ice->state.sampler_table_resource[stage],
+                  &map);
+   if (!unlikely(map))
+      return NULL;
+
+   ice->state.sampler_table_offset[stage] +=
+      bo_offset_from_base_address(ice->state.sampler_table_resource[stage]);
+
    for (int i = 0; i < count; i++) {
-      ice->state.samplers[stage][start + i] = states[i];
+      struct iris_sampler_state *state = states[i];
+
+      /* Save a pointer to the iris_sampler_state, a few fields need
+       * to inform draw-time decisions.
+       */
+      ice->state.samplers[stage][start + i] = state;
+
+      if (state)
+         memcpy(map, state->sampler_state, 4 * GENX(SAMPLER_STATE_length));
+
+      map += GENX(SAMPLER_STATE_length);
    }
 
+   ice->state.num_samplers = count;
+
    ice->state.dirty |= IRIS_DIRTY_SAMPLER_STATES_VS << stage;
 }
 
@@ -2068,12 +2095,10 @@ iris_upload_render_state(struct iris_context *ice,
       }
 
 #if 0
-      for (int i = 0; i < TEXTURES; i++) {
+      for (int i = 0; i < ice->state.num_samplers; i++) {
          struct iris_sampler_view *view = SOMEWHERE;
          struct iris_resource *res = (void *) view->pipe.texture;
-         // XXX: these are per-context??????????? pipe_sampler_view::context
-         *bt_map++ =
-            emit_patched_surface_state(batch, view->surface_state, res, 0);
+         *bt_map++ = use_surface(batch, isv, true);
       }
 
       // XXX: not implemented yet
@@ -2092,26 +2117,9 @@ iris_upload_render_state(struct iris_context *ice,
           !ice->shaders.prog[stage])
          continue;
 
-      // XXX: get sampler count from shader; don't emit them all...
-      const int count = IRIS_MAX_TEXTURE_SAMPLERS;
-
-      uint32_t offset;
-      uint32_t *map = stream_state(batch, ice->state.dynamic_uploader,
-                                   count * 4 * GENX(SAMPLER_STATE_length),
-                                   32, &offset);
-
-      for (int i = 0; i < count; i++) {
-         // XXX: when we have a correct count, these better be bound
-         if (!ice->state.samplers[stage][i])
-            continue;
-         memcpy(map, ice->state.samplers[stage][i]->sampler_state,
-                4 * GENX(SAMPLER_STATE_length));
-         map += GENX(SAMPLER_STATE_length);
-      }
-
       iris_emit_cmd(batch, GENX(3DSTATE_SAMPLER_STATE_POINTERS_VS), ptr) {
          ptr._3DCommandSubOpcode = 43 + stage;
-         ptr.PointertoVSSamplerState = offset;
+         ptr.PointertoVSSamplerState = ice->state.sampler_table_offset[stage];
       }
    }