i965g: hook up pipe sampler callbacks
[mesa.git] / src / gallium / drivers / i965 / brw_wm_surface_state.c
1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
13
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32 #include "pipe/p_format.h"
33
34 #include "brw_batchbuffer.h"
35 #include "brw_context.h"
36 #include "brw_state.h"
37 #include "brw_defines.h"
38 #include "brw_screen.h"
39
40
41
42
43 static void
44 brw_update_texture_surface( struct brw_context *brw,
45 struct brw_texture *tex,
46 GLuint surf )
47 {
48 brw->wm.surf_bo[surf] = brw_search_cache(&brw->surface_cache,
49 BRW_SS_SURFACE,
50 &tex->ss, sizeof tex->ss,
51 &tex->bo, 1,
52 NULL);
53
54 if (brw->wm.surf_bo[surf] == NULL) {
55 brw->wm.surf_bo[surf] = brw_upload_cache(&brw->surface_cache, BRW_SS_SURFACE,
56 &tex->ss, sizeof tex->ss,
57 &tex->bo, 1,
58 &tex->ss, sizeof tex->ss,
59 NULL, NULL);
60
61 /* Emit relocation to surface contents */
62 brw->sws->bo_emit_reloc(brw->wm.surf_bo[surf],
63 BRW_USAGE_SAMPLER,
64 0,
65 offsetof(struct brw_surface_state, ss1),
66 tex->bo);
67 }
68 }
69
70
71
72
73
74
75
76
77 /**
78 * Sets up a surface state structure to point at the given region.
79 * While it is only used for the front/back buffer currently, it should be
80 * usable for further buffers when doing ARB_draw_buffer support.
81 */
82 static void
83 brw_update_renderbuffer_surface(struct brw_context *brw,
84 struct brw_surface *surface,
85 unsigned int unit)
86 {
87 struct brw_surf_ss0 blend_ss0 = brw->curr.blend->ss0;
88 struct brw_surface_state ss;
89
90 /* Surfaces are potentially shared between contexts, so can't
91 * scribble the in-place ss0 value in the surface.
92 */
93 memcpy(&ss, &surface->ss, sizeof ss);
94
95 ss.ss0.color_blend = blend_ss0.color_blend;
96 ss.ss0.writedisable_blue = blend_ss0.writedisable_blue;
97 ss.ss0.writedisable_green = blend_ss0.writedisable_green;
98 ss.ss0.writedisable_red = blend_ss0.writedisable_red;
99 ss.ss0.writedisable_alpha = blend_ss0.writedisable_alpha;
100
101 brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
102 brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
103 BRW_SS_SURFACE,
104 &ss, sizeof(ss),
105 &surface->bo, 1,
106 NULL);
107
108 if (brw->wm.surf_bo[unit] == NULL) {
109
110 brw->wm.surf_bo[unit] = brw_upload_cache(&brw->surface_cache,
111 BRW_SS_SURFACE,
112 &ss, sizeof ss,
113 &surface->bo, 1,
114 &ss, sizeof ss,
115 NULL, NULL);
116
117 /* XXX: we will only be rendering to this surface:
118 */
119 brw->sws->bo_emit_reloc(brw->wm.surf_bo[unit],
120 BRW_USAGE_RENDER_TARGET,
121 ss.ss1.base_addr - surface->bo->offset[0], /* XXX */
122 offsetof(struct brw_surface_state, ss1),
123 surface->bo);
124 }
125 }
126
127
128 /**
129 * Constructs the binding table for the WM surface state, which maps unit
130 * numbers to surface state objects.
131 */
132 static struct brw_winsys_buffer *
133 brw_wm_get_binding_table(struct brw_context *brw)
134 {
135 struct brw_winsys_buffer *bind_bo;
136
137 assert(brw->wm.nr_surfaces <= BRW_WM_MAX_SURF);
138
139 /* Note there is no key for this search beyond the values in the
140 * relocation array:
141 */
142 bind_bo = brw_search_cache(&brw->surface_cache, BRW_SS_SURF_BIND,
143 NULL, 0,
144 brw->wm.surf_bo, brw->wm.nr_surfaces,
145 NULL);
146
147 if (bind_bo == NULL) {
148 uint32_t data[BRW_WM_MAX_SURF];
149 GLuint data_size = brw->wm.nr_surfaces * sizeof data[0];
150 int i;
151
152 for (i = 0; i < brw->wm.nr_surfaces; i++)
153 data[i] = brw->wm.surf_bo[i]->offset[0];
154
155 bind_bo = brw_upload_cache( &brw->surface_cache, BRW_SS_SURF_BIND,
156 NULL, 0,
157 brw->wm.surf_bo, brw->wm.nr_surfaces,
158 data, data_size,
159 NULL, NULL);
160
161 /* Emit binding table relocations to surface state */
162 for (i = 0; i < brw->wm.nr_surfaces; i++) {
163 brw->sws->bo_emit_reloc(bind_bo,
164 BRW_USAGE_STATE,
165 0,
166 i * sizeof(GLuint),
167 brw->wm.surf_bo[i]);
168 }
169 }
170
171 return bind_bo;
172 }
173
174 static int prepare_wm_surfaces(struct brw_context *brw )
175 {
176 GLuint i;
177 int nr_surfaces = 0;
178
179 /* Unreference old buffers
180 */
181 for (i = 0; i < brw->wm.nr_surfaces; i++) {
182 brw->sws->bo_unreference(brw->wm.surf_bo[i]);
183 brw->wm.surf_bo[i] = NULL;
184 }
185
186
187 /* PIPE_NEW_COLOR_BUFFERS | PIPE_NEW_BLEND
188 *
189 * Update surfaces for drawing buffers. Mixes in colormask and
190 * blend state.
191 *
192 * XXX: no color buffer case
193 */
194 for (i = 0; i < brw->curr.fb.nr_cbufs; i++) {
195 brw_update_renderbuffer_surface(brw,
196 brw_surface(brw->curr.fb.cbufs[i]),
197 nr_surfaces++);
198 }
199
200 /* PIPE_NEW_TEXTURE
201 */
202 for (i = 0; i < brw->curr.num_textures; i++) {
203 brw_update_texture_surface(brw,
204 brw_texture(brw->curr.texture[i]),
205 nr_surfaces++);
206 }
207
208 /* PIPE_NEW_FRAGMENT_CONSTANTS
209 */
210 #if 0
211 if (brw->curr.fragment_constants) {
212 brw_update_fragment_constant_surface(brw,
213 brw->curr.fragment_constants,
214 nr_surfaces++);
215 }
216 #endif
217
218 brw->sws->bo_unreference(brw->wm.bind_bo);
219 brw->wm.bind_bo = brw_wm_get_binding_table(brw);
220
221 if (brw->wm.nr_surfaces != nr_surfaces) {
222 brw->wm.nr_surfaces = nr_surfaces;
223 brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
224 }
225
226 return 0;
227 }
228
229 const struct brw_tracked_state brw_wm_surfaces = {
230 .dirty = {
231 .mesa = (PIPE_NEW_COLOR_BUFFERS |
232 PIPE_NEW_BOUND_TEXTURES |
233 PIPE_NEW_FRAGMENT_CONSTANTS |
234 PIPE_NEW_BLEND),
235 .brw = (BRW_NEW_CONTEXT |
236 BRW_NEW_WM_SURFACES),
237 .cache = 0
238 },
239 .prepare = prepare_wm_surfaces,
240 };
241
242
243