i965: Make a brw_stage_prog_data for storing the SURF_INDEX information.
[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 static void
54 brw_upload_binding_table(struct brw_context *brw,
55 GLbitfield brw_new_binding_table,
56 struct brw_stage_state *stage_state)
57 {
58 /* CACHE_NEW_*_PROG */
59 struct brw_stage_prog_data *prog_data = stage_state->prog_data;
60
61 /* If there are no surfaces, skip making the binding table altogether. */
62 if (prog_data->binding_table.size_bytes == 0) {
63 if (stage_state->bind_bo_offset != 0) {
64 brw->state.dirty.brw |= brw_new_binding_table;
65 stage_state->bind_bo_offset = 0;
66 }
67 return;
68 }
69
70 if (INTEL_DEBUG & DEBUG_SHADER_TIME) {
71 gen7_create_shader_time_surface(brw, &stage_state->surf_offset[prog_data->binding_table.shader_time_start]);
72 }
73
74 uint32_t *bind = brw_state_batch(brw, AUB_TRACE_BINDING_TABLE,
75 prog_data->binding_table.size_bytes, 32,
76 &stage_state->bind_bo_offset);
77
78 /* BRW_NEW_SURFACES and BRW_NEW_*_CONSTBUF */
79 memcpy(bind, stage_state->surf_offset, prog_data->binding_table.size_bytes);
80
81 brw->state.dirty.brw |= brw_new_binding_table;
82 }
83
84 /**
85 * State atoms which upload the binding table for a particular shader stage.
86 * @{
87 */
88
89 /** Upload the VS binding table. */
90 static void
91 brw_vs_upload_binding_table(struct brw_context *brw)
92 {
93 brw_upload_binding_table(brw, BRW_NEW_VS_BINDING_TABLE, &brw->vs.base);
94 }
95
96 const struct brw_tracked_state brw_vs_binding_table = {
97 .dirty = {
98 .mesa = 0,
99 .brw = BRW_NEW_BATCH |
100 BRW_NEW_VS_CONSTBUF |
101 BRW_NEW_SURFACES,
102 .cache = CACHE_NEW_VS_PROG
103 },
104 .emit = brw_vs_upload_binding_table,
105 };
106
107
108 /** Upload the PS binding table. */
109 static void
110 brw_upload_wm_binding_table(struct brw_context *brw)
111 {
112 brw_upload_binding_table(brw, BRW_NEW_PS_BINDING_TABLE, &brw->wm.base);
113 }
114
115 const struct brw_tracked_state brw_wm_binding_table = {
116 .dirty = {
117 .mesa = 0,
118 .brw = BRW_NEW_BATCH | BRW_NEW_SURFACES,
119 .cache = CACHE_NEW_WM_PROG
120 },
121 .emit = brw_upload_wm_binding_table,
122 };
123
124 /** Upload the GS binding table (if GS is active). */
125 static void
126 brw_gs_upload_binding_table(struct brw_context *brw)
127 {
128 /* If there's no GS, skip changing anything. */
129 if (!brw->gs.prog_data)
130 return;
131
132 brw_upload_binding_table(brw, BRW_NEW_GS_BINDING_TABLE, &brw->gs.base);
133 }
134
135 const struct brw_tracked_state brw_gs_binding_table = {
136 .dirty = {
137 .mesa = 0,
138 .brw = BRW_NEW_BATCH |
139 BRW_NEW_GS_CONSTBUF |
140 BRW_NEW_SURFACES,
141 .cache = CACHE_NEW_GS_PROG
142 },
143 .emit = brw_gs_upload_binding_table,
144 };
145
146 /** @} */
147
148 /**
149 * State atoms which emit 3DSTATE packets to update the binding table pointers.
150 * @{
151 */
152
153 /**
154 * (Gen4-5) Upload the binding table pointers for all shader stages.
155 *
156 * The binding table pointers are relative to the surface state base address,
157 * which points at the batchbuffer containing the streamed batch state.
158 */
159 static void
160 gen4_upload_binding_table_pointers(struct brw_context *brw)
161 {
162 BEGIN_BATCH(6);
163 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 | (6 - 2));
164 OUT_BATCH(brw->vs.base.bind_bo_offset);
165 OUT_BATCH(0); /* gs */
166 OUT_BATCH(0); /* clip */
167 OUT_BATCH(0); /* sf */
168 OUT_BATCH(brw->wm.base.bind_bo_offset);
169 ADVANCE_BATCH();
170 }
171
172 const struct brw_tracked_state brw_binding_table_pointers = {
173 .dirty = {
174 .mesa = 0,
175 .brw = (BRW_NEW_BATCH |
176 BRW_NEW_STATE_BASE_ADDRESS |
177 BRW_NEW_VS_BINDING_TABLE |
178 BRW_NEW_GS_BINDING_TABLE |
179 BRW_NEW_PS_BINDING_TABLE),
180 .cache = 0,
181 },
182 .emit = gen4_upload_binding_table_pointers,
183 };
184
185 /**
186 * (Sandybridge Only) Upload the binding table pointers for all shader stages.
187 *
188 * The binding table pointers are relative to the surface state base address,
189 * which points at the batchbuffer containing the streamed batch state.
190 */
191 static void
192 gen6_upload_binding_table_pointers(struct brw_context *brw)
193 {
194 BEGIN_BATCH(4);
195 OUT_BATCH(_3DSTATE_BINDING_TABLE_POINTERS << 16 |
196 GEN6_BINDING_TABLE_MODIFY_VS |
197 GEN6_BINDING_TABLE_MODIFY_GS |
198 GEN6_BINDING_TABLE_MODIFY_PS |
199 (4 - 2));
200 OUT_BATCH(brw->vs.base.bind_bo_offset); /* vs */
201 OUT_BATCH(brw->ff_gs.bind_bo_offset); /* gs */
202 OUT_BATCH(brw->wm.base.bind_bo_offset); /* wm/ps */
203 ADVANCE_BATCH();
204 }
205
206 const struct brw_tracked_state gen6_binding_table_pointers = {
207 .dirty = {
208 .mesa = 0,
209 .brw = (BRW_NEW_BATCH |
210 BRW_NEW_STATE_BASE_ADDRESS |
211 BRW_NEW_VS_BINDING_TABLE |
212 BRW_NEW_GS_BINDING_TABLE |
213 BRW_NEW_PS_BINDING_TABLE),
214 .cache = 0,
215 },
216 .emit = gen6_upload_binding_table_pointers,
217 };
218
219 /* Gen7+ code lives in gen7_{vs,gs,wm}_state.c. */
220
221 /** @} */