Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 | GLbitfield brw_new_binding_table, |
||
57 | const struct brw_stage_prog_data *prog_data, |
||
58 | struct brw_stage_state *stage_state) |
||
59 | { |
||
60 | if (prog_data->binding_table.size_bytes == 0) { |
||
61 | /* There are no surfaces; skip making the binding table altogether. */ |
||
62 | if (stage_state->bind_bo_offset == 0 && brw->gen < 9) |
||
63 | return; |
||
64 | |||
65 | stage_state->bind_bo_offset = 0; |
||
66 | } else { |
||
67 | /* Upload a new binding table. */ |
||
68 | if (INTEL_DEBUG & DEBUG_SHADER_TIME) { |
||
69 | brw->vtbl.emit_buffer_surface_state( |
||
70 | brw, &stage_state->surf_offset[ |
||
71 | prog_data->binding_table.shader_time_start], |
||
72 | brw->shader_time.bo, 0, BRW_SURFACEFORMAT_RAW, |
||
73 | brw->shader_time.bo->size, 1, true); |
||
74 | } |
||
75 | |||
76 | uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE, |
||
77 | prog_data->binding_table.size_bytes, 32, |
||
78 | &stage_state->bind_bo_offset); |
||
79 | |||
80 | /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */ |
||
81 | memcpy(bind, stage_state->surf_offset, |
||
82 | prog_data->binding_table.size_bytes); |
||
83 | } |
||
84 | |||
85 | brw->ctx.NewDriverState |= brw_new_binding_table; |
||
86 | |||
87 | if (brw->gen >= 7) { |
||
88 | BEGIN_BATCH(2); |
||
89 | OUT_BATCH(packet_name << 16 | (2 - 2)); |
||
90 | OUT_BATCH(stage_state->bind_bo_offset); |
||
91 | ADVANCE_BATCH(); |
||
92 | } |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * State atoms which upload the binding table for a particular shader stage. |
||
97 | * @{ |
||
98 | */ |
||
99 | |||
100 | /** Upload the VS binding table. */ |
||
101 | static void |
||
102 | brw_vs_upload_binding_table(struct brw_context *brw) |
||
103 | { |
||
104 | /* BRW_NEW_VS_PROG_DATA */ |
||
105 | const struct brw_stage_prog_data *prog_data = brw->vs.base.prog_data; |
||
106 | brw_upload_binding_table(brw, |
||
107 | _3DSTATE_BINDING_TABLE_POINTERS_VS, |
||
108 | BRW_NEW_VS_BINDING_TABLE, prog_data, |
||
109 | &brw->vs.base); |
||
110 | } |
||
111 | |||
112 | const struct brw_tracked_state brw_vs_binding_table = { |
||
113 | .dirty = { |
||
114 | .mesa = 0, |
||
115 | .brw = BRW_NEW_BATCH | |
||
116 | BRW_NEW_VS_CONSTBUF | |
||
117 | BRW_NEW_VS_PROG_DATA | |
||
118 | BRW_NEW_SURFACES, |
||
119 | }, |
||
120 | .emit = brw_vs_upload_binding_table, |
||
121 | }; |
||
122 | |||
123 | |||
124 | /** Upload the PS binding table. */ |
||
125 | static void |
||
126 | brw_upload_wm_binding_table(struct brw_context *brw) |
||
127 | { |
||
128 | /* BRW_NEW_FS_PROG_DATA */ |
||
129 | const struct brw_stage_prog_data *prog_data = brw->wm.base.prog_data; |
||
130 | brw_upload_binding_table(brw, |
||
131 | _3DSTATE_BINDING_TABLE_POINTERS_PS, |
||
132 | BRW_NEW_PS_BINDING_TABLE, prog_data, |
||
133 | &brw->wm.base); |
||
134 | } |
||
135 | |||
136 | const struct brw_tracked_state brw_wm_binding_table = { |
||
137 | .dirty = { |
||
138 | .mesa = 0, |
||
139 | .brw = BRW_NEW_BATCH | |
||
140 | BRW_NEW_FS_PROG_DATA | |
||
141 | BRW_NEW_SURFACES, |
||
142 | }, |
||
143 | .emit = brw_upload_wm_binding_table, |
||
144 | }; |
||
145 | |||
146 | /** Upload the GS binding table (if GS is active). */ |
||
147 | static void |
||
148 | brw_gs_upload_binding_table(struct brw_context *brw) |
||
149 | { |
||
150 | /* If there's no GS, skip changing anything. */ |
||
151 | if (brw->geometry_program == NULL) |
||
152 | return; |
||
153 | |||
154 | /* BRW_NEW_GS_PROG_DATA */ |
||
155 | const struct brw_stage_prog_data *prog_data = brw->gs.base.prog_data; |
||
156 | brw_upload_binding_table(brw, |
||
157 | _3DSTATE_BINDING_TABLE_POINTERS_GS, |
||
158 | BRW_NEW_GS_BINDING_TABLE, prog_data, |
||
159 | &brw->gs.base); |
||
160 | } |
||
161 | |||
162 | const struct brw_tracked_state brw_gs_binding_table = { |
||
163 | .dirty = { |
||
164 | .mesa = 0, |
||
165 | .brw = BRW_NEW_BATCH | |
||
166 | BRW_NEW_GS_CONSTBUF | |
||
167 | BRW_NEW_GS_PROG_DATA | |
||
168 | BRW_NEW_SURFACES, |
||
169 | }, |
||
170 | .emit = brw_gs_upload_binding_table, |
||
171 | }; |
||
172 | |||
173 | /** @} */ |
||
174 | |||
175 | /** |
||
176 | * State atoms which emit 3DSTATE packets to update the binding table pointers. |
||
177 | * @{ |
||
178 | */ |
||
179 | |||
180 | /** |
||
181 | * (Gen4-5) Upload the binding table pointers for all shader stages. |
||
182 | * |
||
183 | * The binding table pointers are relative to the surface state base address, |
||
184 | * which points at the batchbuffer containing the streamed batch state. |
||
185 | */ |
||
186 | static void |
||
187 | gen4_upload_binding_table_pointers(struct brw_context *brw) |
||
188 | { |
||
189 | BEGIN_BATCH(6); |
||
190 | OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2)); |
||
191 | OUT_BATCH(brw->vs.base.bind_bo_offset); |
||
192 | OUT_BATCH(0); /* gs */ |
||
193 | OUT_BATCH(0); /* clip */ |
||
194 | OUT_BATCH(0); /* sf */ |
||
195 | OUT_BATCH(brw->wm.base.bind_bo_offset); |
||
196 | ADVANCE_BATCH(); |
||
197 | } |
||
198 | |||
199 | const struct brw_tracked_state brw_binding_table_pointers = { |
||
200 | .dirty = { |
||
201 | .mesa = 0, |
||
202 | .brw = BRW_NEW_BATCH | |
||
203 | BRW_NEW_GS_BINDING_TABLE | |
||
204 | BRW_NEW_PS_BINDING_TABLE | |
||
205 | BRW_NEW_STATE_BASE_ADDRESS | |
||
206 | BRW_NEW_VS_BINDING_TABLE, |
||
207 | }, |
||
208 | .emit = gen4_upload_binding_table_pointers, |
||
209 | }; |
||
210 | |||
211 | /** |
||
212 | * (Sandybridge Only) Upload the binding table pointers for all shader stages. |
||
213 | * |
||
214 | * The binding table pointers are relative to the surface state base address, |
||
215 | * which points at the batchbuffer containing the streamed batch state. |
||
216 | */ |
||
217 | static void |
||
218 | gen6_upload_binding_table_pointers(struct brw_context *brw) |
||
219 | { |
||
220 | BEGIN_BATCH(4); |
||
221 | OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | |
||
222 | GEN6_BINDING_TABLE_MODIFY_VS | |
||
223 | GEN6_BINDING_TABLE_MODIFY_GS | |
||
224 | GEN6_BINDING_TABLE_MODIFY_PS | |
||
225 | (4 - 2)); |
||
226 | OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */ |
||
227 | if (brw->ff_gs.prog_active) |
||
228 | OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */ |
||
229 | else |
||
230 | OUT_BATCH(brw->gs.base.bind_bo_offset); /* gs */ |
||
231 | OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */ |
||
232 | ADVANCE_BATCH(); |
||
233 | } |
||
234 | |||
235 | const struct brw_tracked_state gen6_binding_table_pointers = { |
||
236 | .dirty = { |
||
237 | .mesa = 0, |
||
238 | .brw = BRW_NEW_BATCH | |
||
239 | BRW_NEW_GS_BINDING_TABLE | |
||
240 | BRW_NEW_PS_BINDING_TABLE | |
||
241 | BRW_NEW_STATE_BASE_ADDRESS | |
||
242 | BRW_NEW_VS_BINDING_TABLE, |
||
243 | }, |
||
244 | .emit = gen6_upload_binding_table_pointers, |
||
245 | }; |
||
246 | |||
247 | /** @} */><>><>><>> |