i965: Drop global bufmgr lock from brw_bo_map_* functions.
[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 uint32_t packet_name,
56 const struct brw_stage_prog_data *prog_data,
57 struct brw_stage_state *stage_state)
58 {
59 if (prog_data->binding_table.size_bytes == 0) {
60 /* There are no surfaces; skip making the binding table altogether. */
61 if (stage_state->bind_bo_offset == 0 && brw->gen < 9)
62 return;
63
64 stage_state->bind_bo_offset = 0;
65 } else {
66 /* Upload a new binding table. */
67 if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
68 brw_emit_buffer_surface_state(
69 brw, &stage_state->surf_offset[
70 prog_data->binding_table.shader_time_start],
71 brw->shader_time.bo, 0, ISL_FORMAT_RAW,
72 brw->shader_time.bo->size, 1, true);
73 }
74 uint32_t *bind =
75 brw_state_batch(brw, prog_data->binding_table.size_bytes,
76 32, &stage_state->bind_bo_offset);
77
78 /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */
79 memcpy(bind, stage_state->surf_offset,
80 prog_data->binding_table.size_bytes);
81 }
82
83 brw->ctx.NewDriverState |= BRW_NEW_BINDING_TABLE_POINTERS;
84
85 if (brw->gen >= 7) {
86 BEGIN_BATCH(2);
87 OUT_BATCH(packet_name << 16 | (2 - 2));
88 /* Align SurfaceStateOffset[16:6] format to [15:5] PS Binding Table field
89 * when hw-generated binding table is enabled.
90 */
91 OUT_BATCH(stage_state->bind_bo_offset);
92 ADVANCE_BATCH();
93 }
94 }
95
96 /**
97 * State atoms which upload the binding table for a particular shader stage.
98 * @{
99 */
100
101 /** Upload the VS binding table. */
102 static void
103 brw_vs_upload_binding_table(struct brw_context *brw)
104 {
105 /* BRW_NEW_VS_PROG_DATA */
106 const struct brw_stage_prog_data *prog_data = brw->vs.base.prog_data;
107 brw_upload_binding_table(brw,
108 _3DSTATE_BINDING_TABLE_POINTERS_VS,
109 prog_data,
110 &brw->vs.base);
111 }
112
113 const struct brw_tracked_state brw_vs_binding_table = {
114 .dirty = {
115 .mesa = 0,
116 .brw = BRW_NEW_BATCH |
117 BRW_NEW_BLORP |
118 BRW_NEW_VS_CONSTBUF |
119 BRW_NEW_VS_PROG_DATA |
120 BRW_NEW_SURFACES,
121 },
122 .emit = brw_vs_upload_binding_table,
123 };
124
125
126 /** Upload the PS binding table. */
127 static void
128 brw_upload_wm_binding_table(struct brw_context *brw)
129 {
130 /* BRW_NEW_FS_PROG_DATA */
131 const struct brw_stage_prog_data *prog_data = brw->wm.base.prog_data;
132 brw_upload_binding_table(brw,
133 _3DSTATE_BINDING_TABLE_POINTERS_PS,
134 prog_data,
135 &brw->wm.base);
136 }
137
138 const struct brw_tracked_state brw_wm_binding_table = {
139 .dirty = {
140 .mesa = 0,
141 .brw = BRW_NEW_BATCH |
142 BRW_NEW_BLORP |
143 BRW_NEW_FS_PROG_DATA |
144 BRW_NEW_SURFACES,
145 },
146 .emit = brw_upload_wm_binding_table,
147 };
148
149 /** Upload the TCS binding table (if tessellation stages are active). */
150 static void
151 brw_tcs_upload_binding_table(struct brw_context *brw)
152 {
153 /* Skip if the tessellation stages are disabled. */
154 if (brw->tess_eval_program == NULL)
155 return;
156
157 /* BRW_NEW_TCS_PROG_DATA */
158 const struct brw_stage_prog_data *prog_data = brw->tcs.base.prog_data;
159 brw_upload_binding_table(brw,
160 _3DSTATE_BINDING_TABLE_POINTERS_HS,
161 prog_data,
162 &brw->tcs.base);
163 }
164
165 const struct brw_tracked_state brw_tcs_binding_table = {
166 .dirty = {
167 .mesa = 0,
168 .brw = BRW_NEW_BATCH |
169 BRW_NEW_BLORP |
170 BRW_NEW_DEFAULT_TESS_LEVELS |
171 BRW_NEW_SURFACES |
172 BRW_NEW_TCS_CONSTBUF |
173 BRW_NEW_TCS_PROG_DATA,
174 },
175 .emit = brw_tcs_upload_binding_table,
176 };
177
178 /** Upload the TES binding table (if TES is active). */
179 static void
180 brw_tes_upload_binding_table(struct brw_context *brw)
181 {
182 /* If there's no TES, skip changing anything. */
183 if (brw->tess_eval_program == NULL)
184 return;
185
186 /* BRW_NEW_TES_PROG_DATA */
187 const struct brw_stage_prog_data *prog_data = brw->tes.base.prog_data;
188 brw_upload_binding_table(brw,
189 _3DSTATE_BINDING_TABLE_POINTERS_DS,
190 prog_data,
191 &brw->tes.base);
192 }
193
194 const struct brw_tracked_state brw_tes_binding_table = {
195 .dirty = {
196 .mesa = 0,
197 .brw = BRW_NEW_BATCH |
198 BRW_NEW_BLORP |
199 BRW_NEW_SURFACES |
200 BRW_NEW_TES_CONSTBUF |
201 BRW_NEW_TES_PROG_DATA,
202 },
203 .emit = brw_tes_upload_binding_table,
204 };
205
206 /** Upload the GS binding table (if GS is active). */
207 static void
208 brw_gs_upload_binding_table(struct brw_context *brw)
209 {
210 /* If there's no GS, skip changing anything. */
211 if (brw->geometry_program == NULL)
212 return;
213
214 /* BRW_NEW_GS_PROG_DATA */
215 const struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data;
216 brw_upload_binding_table(brw,
217 _3DSTATE_BINDING_TABLE_POINTERS_GS,
218 prog_data,
219 &brw->gs.base);
220 }
221
222 const struct brw_tracked_state brw_gs_binding_table = {
223 .dirty = {
224 .mesa = 0,
225 .brw = BRW_NEW_BATCH |
226 BRW_NEW_BLORP |
227 BRW_NEW_GS_CONSTBUF |
228 BRW_NEW_GS_PROG_DATA |
229 BRW_NEW_SURFACES,
230 },
231 .emit = brw_gs_upload_binding_table,
232 };
233 /** @} */
234
235 /**
236 * State atoms which emit 3DSTATE packets to update the binding table pointers.
237 * @{
238 */
239
240 /**
241 * (Gen4-5) Upload the binding table pointers for all shader stages.
242 *
243 * The binding table pointers are relative to the surface state base address,
244 * which points at the batchbuffer containing the streamed batch state.
245 */
246 static void
247 gen4_upload_binding_table_pointers(struct brw_context *brw)
248 {
249 BEGIN_BATCH(6);
250 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2));
251 OUT_BATCH(brw->vs.base.bind_bo_offset);
252 OUT_BATCH(0); /* gs */
253 OUT_BATCH(0); /* clip */
254 OUT_BATCH(0); /* sf */
255 OUT_BATCH(brw->wm.base.bind_bo_offset);
256 ADVANCE_BATCH();
257 }
258
259 const struct brw_tracked_state brw_binding_table_pointers = {
260 .dirty = {
261 .mesa = 0,
262 .brw = BRW_NEW_BATCH |
263 BRW_NEW_BLORP |
264 BRW_NEW_BINDING_TABLE_POINTERS |
265 BRW_NEW_STATE_BASE_ADDRESS,
266 },
267 .emit = gen4_upload_binding_table_pointers,
268 };
269
270 /**
271 * (Sandybridge Only) Upload the binding table pointers for all shader stages.
272 *
273 * The binding table pointers are relative to the surface state base address,
274 * which points at the batchbuffer containing the streamed batch state.
275 */
276 static void
277 gen6_upload_binding_table_pointers(struct brw_context *brw)
278 {
279 BEGIN_BATCH(4);
280 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 |
281 GEN6_BINDING_TABLE_MODIFY_VS |
282 GEN6_BINDING_TABLE_MODIFY_GS |
283 GEN6_BINDING_TABLE_MODIFY_PS |
284 (4 - 2));
285 OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */
286 if (brw->ff_gs.prog_active)
287 OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */
288 else
289 OUT_BATCH(brw->gs.base.bind_bo_offset); /* gs */
290 OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */
291 ADVANCE_BATCH();
292 }
293
294 const struct brw_tracked_state gen6_binding_table_pointers = {
295 .dirty = {
296 .mesa = 0,
297 .brw = BRW_NEW_BATCH |
298 BRW_NEW_BLORP |
299 BRW_NEW_BINDING_TABLE_POINTERS |
300 BRW_NEW_STATE_BASE_ADDRESS,
301 },
302 .emit = gen6_upload_binding_table_pointers,
303 };
304
305 /** @} */