The 3DSTATE_GATHER_POOL_ALLOC is used to enable or disable the gather push constants feature within a context. This patch provides the toggle functionality of using gather push constants to program constant data within a batch.
Using gather push constants require that a gather pool be allocated so that the resource streamer can flush the packed constants it gathered. The pool is later referenced by the 3DSTATE_CONSTANT_* command to program the push constant data. Also introduce INTEL_UBO_GATHER to selectively enable which shader stage uses gather constants for ubo fetches. Signed-off-by: Abdiel Janulgue <abdiel.janul...@linux.intel.com> --- src/mesa/drivers/dri/i965/brw_binding_tables.c | 43 +++++++++++++++++++++++++- src/mesa/drivers/dri/i965/brw_context.c | 37 ++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_context.h | 10 ++++++ src/mesa/drivers/dri/i965/brw_state.h | 1 + 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/mesa/drivers/dri/i965/brw_binding_tables.c b/src/mesa/drivers/dri/i965/brw_binding_tables.c index c1d188e..4793fbc 100644 --- a/src/mesa/drivers/dri/i965/brw_binding_tables.c +++ b/src/mesa/drivers/dri/i965/brw_binding_tables.c @@ -236,9 +236,47 @@ gen7_update_binding_table_from_array(struct brw_context *brw, ADVANCE_BATCH(); } +static void +gen7_init_gather_pool(struct brw_context *brw) +{ + if (!brw->has_resource_streamer) + return; + + if (!brw->gather_pool.bo) { + brw->gather_pool.bo = drm_intel_bo_alloc(brw->bufmgr, "gather_pool", + brw->gather_pool.size, 4096); + brw->gather_pool.next_offset = 0; + } +} + +void +gen7_toggle_gather_constants(struct brw_context *brw, bool enable) +{ + if (enable && !brw->has_resource_streamer) + return; + + uint32_t dw1 = brw->is_haswell ? HSW_GATHER_CONSTANTS_RESERVED : 0; + + BEGIN_BATCH(3); + OUT_BATCH(_3DSTATE_GATHER_POOL_ALLOC << 16 | (3 - 2)); + if (enable) { + dw1 |= SET_FIELD(BRW_GATHER_CONSTANTS_ON, BRW_GATHER_CONSTANTS_ENABLE) | + (brw->is_haswell ? GEN7_MOCS_L3 : 0); + OUT_RELOC(brw->gather_pool.bo, I915_GEM_DOMAIN_SAMPLER, 0, dw1); + OUT_RELOC(brw->gather_pool.bo, I915_GEM_DOMAIN_SAMPLER, 0, + brw->gather_pool.bo->size); + } else { + OUT_BATCH(dw1); + OUT_BATCH(0); + } + ADVANCE_BATCH(); +} + void gen7_disable_hw_binding_tables(struct brw_context *brw) { + gen7_toggle_gather_constants(brw, false); + BEGIN_BATCH(3); OUT_BATCH(_3DSTATE_BINDING_TABLE_POOL_ALLOC << 16 | (3 - 2)); OUT_BATCH(SET_FIELD(BRW_HW_BINDING_TABLE_OFF, BRW_HW_BINDING_TABLE_ENABLE) | @@ -280,6 +318,9 @@ gen7_enable_hw_binding_tables(struct brw_context *brw) brw->hw_bt_pool.bo->size); ADVANCE_BATCH(); + gen7_init_gather_pool(brw); + gen7_toggle_gather_constants(brw, true); + /* Pipe control workaround */ brw_emit_pipe_control_flush(brw, PIPE_CONTROL_STATE_CACHE_INVALIDATE); } @@ -288,6 +329,7 @@ void gen7_reset_rs_pool_offsets(struct brw_context *brw) { brw->hw_bt_pool.next_offset = HW_BT_START_OFFSET; + brw->gather_pool.next_offset = 0; } const struct brw_tracked_state gen7_hw_binding_tables = { @@ -371,5 +413,4 @@ const struct brw_tracked_state gen6_binding_table_pointers = { }, .emit = gen6_upload_binding_table_pointers, }; - /** @} */ diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 9c7ccae..685ca70 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -67,6 +67,7 @@ #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "util/ralloc.h" +#include "util/u_atomic.h" #include "glsl/nir/nir.h" @@ -692,6 +693,25 @@ brw_get_revision(int fd) return revision; } +static void +brw_process_intel_gather_variable(struct brw_context *brw) +{ + uint64_t INTEL_UBO_GATHER = 0; + + static const struct dri_debug_control gather_control[] = { + { "vs", (1 << MESA_SHADER_VERTEX)}, + { "gs", (1 << MESA_SHADER_GEOMETRY)}, + { "fs", (1 << MESA_SHADER_FRAGMENT)}, + { NULL, 0 } + }; + uint64_t intel_ubo_gather = driParseDebugString(getenv("INTEL_UBO_GATHER"), gather_control); + (void) p_atomic_cmpxchg(&INTEL_UBO_GATHER, 0, intel_ubo_gather); + + brw->vs_ubo_gather = (INTEL_UBO_GATHER & (1 << MESA_SHADER_VERTEX)); + brw->gs_ubo_gather = (INTEL_UBO_GATHER & (1 << MESA_SHADER_GEOMETRY)); + brw->fs_ubo_gather = (INTEL_UBO_GATHER & (1 << MESA_SHADER_FRAGMENT)); +} + GLboolean brwCreateContext(gl_api api, const struct gl_config *mesaVis, @@ -755,6 +775,10 @@ brwCreateContext(gl_api api, brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil; brw->has_swizzling = screen->hw_has_swizzling; + brw_process_intel_gather_variable(brw); + brw->has_resource_streamer = brw->is_haswell && + (brw->vs_ubo_gather || brw->gs_ubo_gather || brw->fs_ubo_gather); + brw->vs.base.stage = MESA_SHADER_VERTEX; brw->gs.base.stage = MESA_SHADER_GEOMETRY; brw->wm.base.stage = MESA_SHADER_FRAGMENT; @@ -900,6 +924,16 @@ brwCreateContext(gl_api api, if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB; + /* The gather pool is required by the hardware to represent all combined + * constants gathered from various sources where it is then fed into the push + * constant state. There is no fixed amount how many constant + * states are uploaded per batch, so use the combined per-stage limits instead. + */ + brw->gather_pool.size = + brw->ctx.Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents + + brw->ctx.Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents + + brw->ctx.Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents; + if (INTEL_DEBUG & DEBUG_SHADER_TIME) brw_init_shader_time(brw); @@ -954,7 +988,10 @@ intelDestroyContext(__DRIcontext * driContextPriv) drm_intel_bo_unreference(brw->wm.base.scratch_bo); gen7_reset_rs_pool_offsets(brw); + drm_intel_bo_unreference(brw->gather_pool.bo); drm_intel_bo_unreference(brw->hw_bt_pool.bo); + + brw->gather_pool.bo = NULL; brw->hw_bt_pool.bo = NULL; drm_intel_gem_context_destroy(brw->hw_ctx); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 1c72b74..7fd49e9 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -1106,6 +1106,9 @@ struct brw_context bool use_rep_send; bool scalar_vs; bool has_resource_streamer; + bool vs_ubo_gather; + bool gs_ubo_gather; + bool fs_ubo_gather; /** * Some versions of Gen hardware don't do centroid interpolation correctly @@ -1366,6 +1369,13 @@ struct brw_context uint32_t next_offset; } hw_bt_pool; + /* Internal storage used by the resource streamer to flush and refer to constant data*/ + struct { + drm_intel_bo *bo; + uint32_t next_offset; + uint32_t size; + } gather_pool; + struct { uint32_t state_offset; uint32_t blend_state_offset; diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 129a780..342157d 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -312,6 +312,7 @@ void gen7_update_binding_table_from_array(struct brw_context *brw, void gen7_enable_hw_binding_tables(struct brw_context *brw); void gen7_disable_hw_binding_tables(struct brw_context *brw); void gen7_reset_rs_pool_offsets(struct brw_context *brw); +void gen7_toggle_gather_constants(struct brw_context *brw, bool enable); #ifdef __cplusplus } -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev