From feaad189b45cafe860b5f23bf534618ff30b5bd2 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 13 Sep 2013 15:55:03 -0700 Subject: [PATCH] i965: Move binding table code to a new file, brw_binding_tables.c. The code to upload the binding tables for each stage was scattered across brw_{vs,gs,wm}_surface_state.c and brw_misc_state.c, which also contain a lot of code to populate individual SURFACE_STATE structures. This patch brings all the binding table upload code together, and splits it out from the code which fills in SURFACE_STATE entries. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/Makefile.sources | 1 + .../drivers/dri/i965/brw_binding_tables.c | 242 ++++++++++++++++++ .../drivers/dri/i965/brw_gs_surface_state.c | 34 --- src/mesa/drivers/dri/i965/brw_misc_state.c | 66 ----- .../drivers/dri/i965/brw_vs_surface_state.c | 62 ----- .../drivers/dri/i965/brw_wm_surface_state.c | 25 -- 6 files changed, 243 insertions(+), 187 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/brw_binding_tables.c diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 4063bf15b99..f521daaf719 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -27,6 +27,7 @@ i965_FILES = \ intel_tex_subimage.c \ intel_tex_validate.c \ intel_upload.c \ + brw_binding_tables.c \ brw_blorp.cpp \ brw_blorp_blit.cpp \ brw_blorp_clear.cpp \ diff --git a/src/mesa/drivers/dri/i965/brw_binding_tables.c b/src/mesa/drivers/dri/i965/brw_binding_tables.c new file mode 100644 index 00000000000..9d15bac270e --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_binding_tables.c @@ -0,0 +1,242 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * \file brw_binding_tables.c + * + * State atoms which upload the "binding table" for each shader stage. + * + * Binding tables map a numeric "surface index" to the SURFACE_STATE structure + * for a currently bound surface. This allows SEND messages (such as sampler + * or data port messages) to refer to a particular surface by number, rather + * than by pointer. + * + * The binding table is stored as a (sparse) array of SURFACE_STATE entries; + * surface indexes are simply indexes into the array. The ordering of the + * entries is entirely left up to software; see the SURF_INDEX_* macros in + * brw_context.h to see our current layout. + */ + +#include "main/mtypes.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "intel_batchbuffer.h" + +/** + * Upload a shader stage's binding table as indirect state. + * + * This copies brw_stage_state::surf_offset[] into the indirect state section + * of the batchbuffer (allocated by brw_state_batch()). + */ +void +brw_upload_binding_table(struct brw_context *brw, + GLbitfield brw_new_binding_table, + struct brw_stage_state *stage_state, + unsigned binding_table_entries, + int shader_time_surf_index) +{ + if (INTEL_DEBUG & DEBUG_SHADER_TIME) { + gen7_create_shader_time_surface(brw, &stage_state->surf_offset[shader_time_surf_index]); + } + + /* If there are no surfaces, skip making the binding table altogether. */ + if (binding_table_entries == 0) { + if (stage_state->bind_bo_offset != 0) { + brw->state.dirty.brw |= brw_new_binding_table; + stage_state->bind_bo_offset = 0; + } + return; + } + + size_t table_size_in_bytes = binding_table_entries * sizeof(uint32_t); + + uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, + table_size_in_bytes, 32, + &stage_state->bind_bo_offset); + + /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */ + memcpy(bind, stage_state->surf_offset, table_size_in_bytes); + + brw->state.dirty.brw |= brw_new_binding_table; +} + +/** + * State atoms which upload the binding table for a particular shader stage. + * @{ + */ + +/** Upload the VS binding table. */ +static void +brw_vs_upload_binding_table(struct brw_context *brw) +{ + struct brw_stage_state *stage_state = &brw->vs.base; + /* CACHE_NEW_VS_PROG */ + const struct brw_vec4_prog_data *prog_data = &brw->vs.prog_data->base; + + /* BRW_NEW_SURFACES and BRW_NEW_VS_CONSTBUF */ + brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, stage_state, + prog_data->binding_table_size, + SURF_INDEX_VEC4_SHADER_TIME); +} + +const struct brw_tracked_state brw_vs_binding_table = { + .dirty = { + .mesa = 0, + .brw = BRW_NEW_BATCH | + BRW_NEW_VS_CONSTBUF | + BRW_NEW_SURFACES, + .cache = CACHE_NEW_VS_PROG + }, + .emit = brw_vs_upload_binding_table, +}; + + +/** Upload the PS binding table. */ +static void +brw_upload_wm_binding_table(struct brw_context *brw) +{ + struct brw_stage_state *stage_state = &brw->wm.base; + + /* BRW_NEW_SURFACES and CACHE_NEW_WM_PROG */ + brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, stage_state, + brw->wm.prog_data->binding_table_size, + SURF_INDEX_WM_SHADER_TIME); +} + +const struct brw_tracked_state brw_wm_binding_table = { + .dirty = { + .mesa = 0, + .brw = BRW_NEW_BATCH | BRW_NEW_SURFACES, + .cache = CACHE_NEW_WM_PROG + }, + .emit = brw_upload_wm_binding_table, +}; + +/** Upload the GS binding table (if GS is active). */ +static void +brw_gs_upload_binding_table(struct brw_context *brw) +{ + struct brw_stage_state *stage_state = &brw->gs.base; + + /* If there's no GS, skip changing anything. */ + if (!brw->gs.prog_data) + return; + + /* CACHE_NEW_GS_PROG */ + const struct brw_vec4_prog_data *prog_data = &brw->gs.prog_data->base; + + /* BRW_NEW_SURFACES and BRW_NEW_GS_CONSTBUF */ + brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, stage_state, + prog_data->binding_table_size, + SURF_INDEX_VEC4_SHADER_TIME); +} + +const struct brw_tracked_state brw_gs_binding_table = { + .dirty = { + .mesa = 0, + .brw = BRW_NEW_BATCH | + BRW_NEW_GS_CONSTBUF | + BRW_NEW_SURFACES, + .cache = CACHE_NEW_GS_PROG + }, + .emit = brw_gs_upload_binding_table, +}; + +/** @} */ + +/** + * State atoms which emit 3DSTATE packets to update the binding table pointers. + * @{ + */ + +/** + * (Gen4-5) Upload the binding table pointers for all shader stages. + * + * The binding table pointers are relative to the surface state base address, + * which points at the batchbuffer containing the streamed batch state. + */ +static void +gen4_upload_binding_table_pointers(struct brw_context *brw) +{ + BEGIN_BATCH(6); + OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2)); + OUT_BATCH(brw->vs.base.bind_bo_offset); + OUT_BATCH(0); /* gs */ + OUT_BATCH(0); /* clip */ + OUT_BATCH(0); /* sf */ + OUT_BATCH(brw->wm.base.bind_bo_offset); + ADVANCE_BATCH(); +} + +const struct brw_tracked_state brw_binding_table_pointers = { + .dirty = { + .mesa = 0, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS | + BRW_NEW_VS_BINDING_TABLE | + BRW_NEW_GS_BINDING_TABLE | + BRW_NEW_PS_BINDING_TABLE), + .cache = 0, + }, + .emit = gen4_upload_binding_table_pointers, +}; + +/** + * (Sandybridge Only) Upload the binding table pointers for all shader stages. + * + * The binding table pointers are relative to the surface state base address, + * which points at the batchbuffer containing the streamed batch state. + */ +static void +gen6_upload_binding_table_pointers(struct brw_context *brw) +{ + BEGIN_BATCH(4); + OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | + GEN6_BINDING_TABLE_MODIFY_VS | + GEN6_BINDING_TABLE_MODIFY_GS | + GEN6_BINDING_TABLE_MODIFY_PS | + (4 - 2)); + OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */ + OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */ + OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */ + ADVANCE_BATCH(); +} + +const struct brw_tracked_state gen6_binding_table_pointers = { + .dirty = { + .mesa = 0, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS | + BRW_NEW_VS_BINDING_TABLE | + BRW_NEW_GS_BINDING_TABLE | + BRW_NEW_PS_BINDING_TABLE), + .cache = 0, + }, + .emit = gen6_upload_binding_table_pointers, +}; + +/* Gen7+ code lives in gen7_{vs,gs,wm}_state.c. */ + +/** @} */ diff --git a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c index ad4c0035e8f..d0ce412e846 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_gs_surface_state.c @@ -87,37 +87,3 @@ const struct brw_tracked_state brw_gs_ubo_surfaces = { }, .emit = brw_upload_gs_ubo_surfaces, }; - - -/** - * Constructs the binding table for the WM surface state, which maps unit - * numbers to surface state objects. - */ -static void -brw_gs_upload_binding_table(struct brw_context *brw) -{ - struct brw_stage_state *stage_state = &brw->gs.base; - - /* If there's no GS, skip changing anything. */ - if (!brw->gs.prog_data) - return; - - /* CACHE_NEW_GS_PROG */ - const struct brw_vec4_prog_data *prog_data = &brw->gs.prog_data->base; - - /* BRW_NEW_SURFACES and BRW_NEW_GS_CONSTBUF */ - brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, stage_state, - prog_data->binding_table_size, - SURF_INDEX_VEC4_SHADER_TIME); -} - -const struct brw_tracked_state brw_gs_binding_table = { - .dirty = { - .mesa = 0, - .brw = (BRW_NEW_BATCH | - BRW_NEW_GS_CONSTBUF | - BRW_NEW_SURFACES), - .cache = CACHE_NEW_GS_PROG - }, - .emit = brw_gs_upload_binding_table, -}; diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index a95149369a5..7f4cd6f737d 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -66,72 +66,6 @@ const struct brw_tracked_state brw_drawing_rect = { .emit = upload_drawing_rect }; -/** - * Upload the binding table pointers, which point each stage's array of surface - * state pointers. - * - * The binding table pointers are relative to the surface state base address, - * which points at the batchbuffer containing the streamed batch state. - */ -static void upload_binding_table_pointers(struct brw_context *brw) -{ - BEGIN_BATCH(6); - OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2)); - OUT_BATCH(brw->vs.base.bind_bo_offset); - OUT_BATCH(0); /* gs */ - OUT_BATCH(0); /* clip */ - OUT_BATCH(0); /* sf */ - OUT_BATCH(brw->wm.base.bind_bo_offset); - ADVANCE_BATCH(); -} - -const struct brw_tracked_state brw_binding_table_pointers = { - .dirty = { - .mesa = 0, - .brw = (BRW_NEW_BATCH | - BRW_NEW_STATE_BASE_ADDRESS | - BRW_NEW_VS_BINDING_TABLE | - BRW_NEW_GS_BINDING_TABLE | - BRW_NEW_PS_BINDING_TABLE), - .cache = 0, - }, - .emit = upload_binding_table_pointers, -}; - -/** - * Upload the binding table pointers, which point each stage's array of surface - * state pointers. - * - * The binding table pointers are relative to the surface state base address, - * which points at the batchbuffer containing the streamed batch state. - */ -static void upload_gen6_binding_table_pointers(struct brw_context *brw) -{ - BEGIN_BATCH(4); - OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | - GEN6_BINDING_TABLE_MODIFY_VS | - GEN6_BINDING_TABLE_MODIFY_GS | - GEN6_BINDING_TABLE_MODIFY_PS | - (4 - 2)); - OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */ - OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */ - OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */ - ADVANCE_BATCH(); -} - -const struct brw_tracked_state gen6_binding_table_pointers = { - .dirty = { - .mesa = 0, - .brw = (BRW_NEW_BATCH | - BRW_NEW_STATE_BASE_ADDRESS | - BRW_NEW_VS_BINDING_TABLE | - BRW_NEW_GS_BINDING_TABLE | - BRW_NEW_PS_BINDING_TABLE), - .cache = 0, - }, - .emit = upload_gen6_binding_table_pointers, -}; - /** * Upload pointers to the per-stage state. * diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c index 6fbe8ebad25..2c5d06fc41a 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c @@ -148,65 +148,3 @@ const struct brw_tracked_state brw_vs_ubo_surfaces = { }, .emit = brw_upload_vs_ubo_surfaces, }; - - -void -brw_upload_binding_table(struct brw_context *brw, - GLbitfield brw_new_binding_table, - struct brw_stage_state *stage_state, - unsigned binding_table_entries, - int shader_time_surf_index) -{ - if (INTEL_DEBUG & DEBUG_SHADER_TIME) { - gen7_create_shader_time_surface(brw, &stage_state->surf_offset[shader_time_surf_index]); - } - - /* If there are no surfaces, skip making the binding table altogether. */ - if (binding_table_entries == 0) { - if (stage_state->bind_bo_offset != 0) { - brw->state.dirty.brw |= brw_new_binding_table; - stage_state->bind_bo_offset = 0; - } - return; - } - - size_t table_size_in_bytes = binding_table_entries * sizeof(uint32_t); - - uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, - table_size_in_bytes, 32, - &stage_state->bind_bo_offset); - - /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */ - memcpy(bind, stage_state->surf_offset, table_size_in_bytes); - - brw->state.dirty.brw |= brw_new_binding_table; -} - - -/** - * Constructs the binding table for the WM surface state, which maps unit - * numbers to surface state objects. - */ -static void -brw_vs_upload_binding_table(struct brw_context *brw) -{ - struct brw_stage_state *stage_state = &brw->vs.base; - /* CACHE_NEW_VS_PROG */ - const struct brw_vec4_prog_data *prog_data = &brw->vs.prog_data->base; - - /* BRW_NEW_SURFACES and BRW_NEW_VS_CONSTBUF */ - brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, stage_state, - prog_data->binding_table_size, - SURF_INDEX_VEC4_SHADER_TIME); -} - -const struct brw_tracked_state brw_vs_binding_table = { - .dirty = { - .mesa = 0, - .brw = (BRW_NEW_BATCH | - BRW_NEW_VS_CONSTBUF | - BRW_NEW_SURFACES), - .cache = CACHE_NEW_VS_PROG - }, - .emit = brw_vs_upload_binding_table, -}; diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index a7daa0a6d08..52973d6da47 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -855,31 +855,6 @@ const struct brw_tracked_state brw_wm_ubo_surfaces = { .emit = brw_upload_wm_ubo_surfaces, }; -/** - * Constructs the binding table for the WM surface state, which maps unit - * numbers to surface state objects. - */ -static void -brw_upload_wm_binding_table(struct brw_context *brw) -{ - struct brw_stage_state *stage_state = &brw->wm.base; - - /* BRW_NEW_SURFACES and CACHE_NEW_WM_PROG */ - brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, stage_state, - brw->wm.prog_data->binding_table_size, - SURF_INDEX_WM_SHADER_TIME); -} - -const struct brw_tracked_state brw_wm_binding_table = { - .dirty = { - .mesa = 0, - .brw = (BRW_NEW_BATCH | - BRW_NEW_SURFACES), - .cache = CACHE_NEW_WM_PROG - }, - .emit = brw_upload_wm_binding_table, -}; - void gen4_init_vtable_surface_functions(struct brw_context *brw) { -- 2.30.2