summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_binding_tables.c
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2013-09-13 15:55:03 -0700
committerKenneth Graunke <kenneth@whitecape.org>2013-09-19 10:52:57 -0700
commitfeaad189b45cafe860b5f23bf534618ff30b5bd2 (patch)
tree03371c01d88a0b8ab1e7d80c557b229f43464952 /src/mesa/drivers/dri/i965/brw_binding_tables.c
parent113a75ff2d5013583bc41f5bd71e24d7897cd459 (diff)
downloadexternal_mesa3d-feaad189b45cafe860b5f23bf534618ff30b5bd2.zip
external_mesa3d-feaad189b45cafe860b5f23bf534618ff30b5bd2.tar.gz
external_mesa3d-feaad189b45cafe860b5f23bf534618ff30b5bd2.tar.bz2
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 <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_binding_tables.c')
-rw-r--r--src/mesa/drivers/dri/i965/brw_binding_tables.c242
1 files changed, 242 insertions, 0 deletions
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 0000000..9d15bac
--- /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. */
+
+/** @} */