summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2018-04-07 00:49:12 -0700
committerKenneth Graunke <[email protected]>2019-02-21 10:26:05 -0800
commit0707ff3f2f31d9b72aebd169e9464c5fbfaa00ca (patch)
tree1962bd69225e6495c41643387c78129421fa02fc
parent199c0809266adff16ab127f9953d37e8f6c42a76 (diff)
iris: assemble SAMPLER_STATE table at bind time
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.
-rw-r--r--src/gallium/drivers/iris/iris_context.h5
-rw-r--r--src/gallium/drivers/iris/iris_state.c54
2 files changed, 36 insertions, 23 deletions
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index 51eabf91e4b..21e81d37477 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -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);
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 20b2c29abbc..a0f6a685b43 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -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];
}
}