i965: Move binding table code to a new file, brw_binding_tables.c.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_binding_tables.c
1 /*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 /**
25 * \file brw_binding_tables.c
26 *
27 * State atoms which upload the "binding table" for each shader stage.
28 *
29 * Binding tables map a numeric "surface index" to the SURFACE_STATE structure
30 * for a currently bound surface. This allows SEND messages (such as sampler
31 * or data port messages) to refer to a particular surface by number, rather
32 * than by pointer.
33 *
34 * The binding table is stored as a (sparse) array of SURFACE_STATE entries;
35 * surface indexes are simply indexes into the array. The ordering of the
36 * entries is entirely left up to software; see the SURF_INDEX_* macros in
37 * brw_context.h to see our current layout.
38 */
39
40 #include "main/mtypes.h"
41
42 #include "brw_context.h"
43 #include "brw_defines.h"
44 #include "brw_state.h"
45 #include "intel_batchbuffer.h"
46
47 /**
48 * Upload a shader stage's binding table as indirect state.
49 *
50 * This copies brw_stage_state::surf_offset[] into the indirect state section
51 * of the batchbuffer (allocated by brw_state_batch()).
52 */
53 void
54 brw_upload_binding_table(struct brw_context *brw,
55 GLbitfield brw_new_binding_table,
56 struct brw_stage_state *stage_state,
57 unsigned binding_table_entries,
58 int shader_time_surf_index)
59 {
60 if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
61 gen7_create_shader_time_surface(brw, &stage_state->surf_offset[shader_time_surf_index]);
62 }
63
64 /* If there are no surfaces, skip making the binding table altogether. */
65 if (binding_table_entries == 0) {
66 if (stage_state->bind_bo_offset != 0) {
67 brw->state.dirty.brw |= brw_new_binding_table;
68 stage_state->bind_bo_offset = 0;
69 }
70 return;
71 }
72
73 size_t table_size_in_bytes = binding_table_entries * sizeof(uint32_t);
74
75 uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
76 table_size_in_bytes, 32,
77 &stage_state->bind_bo_offset);
78
79 /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */
80 memcpy(bind, stage_state->surf_offset, table_size_in_bytes);
81
82 brw->state.dirty.brw |= brw_new_binding_table;
83 }
84
85 /**
86 * State atoms which upload the binding table for a particular shader stage.
87 * @{
88 */
89
90 /** Upload the VS binding table. */
91 static void
92 brw_vs_upload_binding_table(struct brw_context *brw)
93 {
94 struct brw_stage_state *stage_state = &brw->vs.base;
95 /* CACHE_NEW_VS_PROG */
96 const struct brw_vec4_prog_data *prog_data = &brw->vs.prog_data->base;
97
98 /* BRW_NEW_SURFACES and BRW_NEW_VS_CONSTBUF */
99 brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, stage_state,
100 prog_data->binding_table_size,
101 SURF_INDEX_VEC4_SHADER_TIME);
102 }
103
104 const struct brw_tracked_state brw_vs_binding_table = {
105 .dirty = {
106 .mesa = 0,
107 .brw = BRW_NEW_BATCH |
108 BRW_NEW_VS_CONSTBUF |
109 BRW_NEW_SURFACES,
110 .cache = CACHE_NEW_VS_PROG
111 },
112 .emit = brw_vs_upload_binding_table,
113 };
114
115
116 /** Upload the PS binding table. */
117 static void
118 brw_upload_wm_binding_table(struct brw_context *brw)
119 {
120 struct brw_stage_state *stage_state = &brw->wm.base;
121
122 /* BRW_NEW_SURFACES and CACHE_NEW_WM_PROG */
123 brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, stage_state,
124 brw->wm.prog_data->binding_table_size,
125 SURF_INDEX_WM_SHADER_TIME);
126 }
127
128 const struct brw_tracked_state brw_wm_binding_table = {
129 .dirty = {
130 .mesa = 0,
131 .brw = BRW_NEW_BATCH | BRW_NEW_SURFACES,
132 .cache = CACHE_NEW_WM_PROG
133 },
134 .emit = brw_upload_wm_binding_table,
135 };
136
137 /** Upload the GS binding table (if GS is active). */
138 static void
139 brw_gs_upload_binding_table(struct brw_context *brw)
140 {
141 struct brw_stage_state *stage_state = &brw->gs.base;
142
143 /* If there's no GS, skip changing anything. */
144 if (!brw->gs.prog_data)
145 return;
146
147 /* CACHE_NEW_GS_PROG */
148 const struct brw_vec4_prog_data *prog_data = &brw->gs.prog_data->base;
149
150 /* BRW_NEW_SURFACES and BRW_NEW_GS_CONSTBUF */
151 brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, stage_state,
152 prog_data->binding_table_size,
153 SURF_INDEX_VEC4_SHADER_TIME);
154 }
155
156 const struct brw_tracked_state brw_gs_binding_table = {
157 .dirty = {
158 .mesa = 0,
159 .brw = BRW_NEW_BATCH |
160 BRW_NEW_GS_CONSTBUF |
161 BRW_NEW_SURFACES,
162 .cache = CACHE_NEW_GS_PROG
163 },
164 .emit = brw_gs_upload_binding_table,
165 };
166
167 /** @} */
168
169 /**
170 * State atoms which emit 3DSTATE packets to update the binding table pointers.
171 * @{
172 */
173
174 /**
175 * (Gen4-5) Upload the binding table pointers for all shader stages.
176 *
177 * The binding table pointers are relative to the surface state base address,
178 * which points at the batchbuffer containing the streamed batch state.
179 */
180 static void
181 gen4_upload_binding_table_pointers(struct brw_context *brw)
182 {
183 BEGIN_BATCH(6);
184 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2));
185 OUT_BATCH(brw->vs.base.bind_bo_offset);
186 OUT_BATCH(0); /* gs */
187 OUT_BATCH(0); /* clip */
188 OUT_BATCH(0); /* sf */
189 OUT_BATCH(brw->wm.base.bind_bo_offset);
190 ADVANCE_BATCH();
191 }
192
193 const struct brw_tracked_state brw_binding_table_pointers = {
194 .dirty = {
195 .mesa = 0,
196 .brw = (BRW_NEW_BATCH |
197 BRW_NEW_STATE_BASE_ADDRESS |
198 BRW_NEW_VS_BINDING_TABLE |
199 BRW_NEW_GS_BINDING_TABLE |
200 BRW_NEW_PS_BINDING_TABLE),
201 .cache = 0,
202 },
203 .emit = gen4_upload_binding_table_pointers,
204 };
205
206 /**
207 * (Sandybridge Only) Upload the binding table pointers for all shader stages.
208 *
209 * The binding table pointers are relative to the surface state base address,
210 * which points at the batchbuffer containing the streamed batch state.
211 */
212 static void
213 gen6_upload_binding_table_pointers(struct brw_context *brw)
214 {
215 BEGIN_BATCH(4);
216 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 |
217 GEN6_BINDING_TABLE_MODIFY_VS |
218 GEN6_BINDING_TABLE_MODIFY_GS |
219 GEN6_BINDING_TABLE_MODIFY_PS |
220 (4 - 2));
221 OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */
222 OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */
223 OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */
224 ADVANCE_BATCH();
225 }
226
227 const struct brw_tracked_state gen6_binding_table_pointers = {
228 .dirty = {
229 .mesa = 0,
230 .brw = (BRW_NEW_BATCH |
231 BRW_NEW_STATE_BASE_ADDRESS |
232 BRW_NEW_VS_BINDING_TABLE |
233 BRW_NEW_GS_BINDING_TABLE |
234 BRW_NEW_PS_BINDING_TABLE),
235 .cache = 0,
236 },
237 .emit = gen6_upload_binding_table_pointers,
238 };
239
240 /* Gen7+ code lives in gen7_{vs,gs,wm}_state.c. */
241
242 /** @} */