i965g: more work on compilation -- surface management
[mesa.git] / src / gallium / drivers / i965 / brw_screen_surface.c
1
2 #include "pipe/p_screen.h"
3 #include "brw_screen.h"
4
5
6 /**
7 * Sets up a surface state structure to point at the given region.
8 * While it is only used for the front/back buffer currently, it should be
9 * usable for further buffers when doing ARB_draw_buffer support.
10 */
11 static void
12 brw_update_renderbuffer_surface(struct brw_context *brw,
13 struct gl_renderbuffer *rb,
14 unsigned int unit)
15 {
16 struct brw_winsys_buffer *region_bo = NULL;
17 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
18 struct intel_region *region = irb ? irb->region : NULL;
19 struct {
20 unsigned int surface_type;
21 unsigned int surface_format;
22 unsigned int width, height, pitch, cpp;
23 GLubyte color_mask[4];
24 GLboolean color_blend;
25 uint32_t tiling;
26 uint32_t draw_offset;
27 } key;
28
29 memset(&key, 0, sizeof(key));
30
31 if (region != NULL) {
32 region_bo = region->buffer;
33
34 key.surface_type = BRW_SURFACE_2D;
35 switch (irb->texformat->MesaFormat) {
36 case PIPE_FORMAT_ARGB8888:
37 key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
38 break;
39 case PIPE_FORMAT_RGB565:
40 key.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
41 break;
42 case PIPE_FORMAT_ARGB1555:
43 key.surface_format = BRW_SURFACEFORMAT_B5G5R5A1_UNORM;
44 break;
45 case PIPE_FORMAT_ARGB4444:
46 key.surface_format = BRW_SURFACEFORMAT_B4G4R4A4_UNORM;
47 break;
48 default:
49 debug_printf("Bad renderbuffer format: %d\n",
50 irb->texformat->MesaFormat);
51 assert(0);
52 key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
53 return;
54 }
55 key.tiling = region->tiling;
56 if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
57 key.width = rb->Width;
58 key.height = rb->Height;
59 } else {
60 key.width = region->width;
61 key.height = region->height;
62 }
63 key.pitch = region->pitch;
64 key.cpp = region->cpp;
65 key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
66 }
67
68 memcpy(key.color_mask, ctx->Color.ColorMask,
69 sizeof(key.color_mask));
70
71 key.color_blend = (!ctx->Color._LogicOpEnabled &&
72 ctx->Color.BlendEnabled);
73
74 brw->sws->bo_unreference(brw->wm.surf_bo[unit]);
75 brw->wm.surf_bo[unit] = brw_search_cache(&brw->surface_cache,
76 BRW_SS_SURFACE,
77 &key, sizeof(key),
78 &region_bo, 1,
79 NULL);
80
81 if (brw->wm.surf_bo[unit] == NULL) {
82 struct brw_surface_state surf;
83
84 memset(&surf, 0, sizeof(surf));
85
86 surf.ss0.surface_format = key.surface_format;
87 surf.ss0.surface_type = key.surface_type;
88 if (key.tiling == I915_TILING_NONE) {
89 surf.ss1.base_addr = key.draw_offset;
90 } else {
91 uint32_t tile_offset = key.draw_offset % 4096;
92
93 surf.ss1.base_addr = key.draw_offset - tile_offset;
94
95 assert(BRW_IS_G4X(brw) || tile_offset == 0);
96 if (BRW_IS_G4X(brw)) {
97 if (key.tiling == I915_TILING_X) {
98 /* Note that the low bits of these fields are missing, so
99 * there's the possibility of getting in trouble.
100 */
101 surf.ss5.x_offset = (tile_offset % 512) / key.cpp / 4;
102 surf.ss5.y_offset = tile_offset / 512 / 2;
103 } else {
104 surf.ss5.x_offset = (tile_offset % 128) / key.cpp / 4;
105 surf.ss5.y_offset = tile_offset / 128 / 2;
106 }
107 }
108 }
109
110 if (region_bo != NULL)
111 surf.ss1.base_addr += region_bo->offset; /* reloc */
112
113 surf.ss2.width = key.width - 1;
114 surf.ss2.height = key.height - 1;
115 brw_set_surface_tiling(&surf, key.tiling);
116 surf.ss3.pitch = (key.pitch * key.cpp) - 1;
117
118 }
119
120
121
122 struct brw_surface_id {
123 unsigned face:3;
124 unsigned zslice:13;
125 unsigned level:16;
126 };
127
128 static boolean need_linear_view( struct brw_screen *brw_screen,
129 struct brw_texture *brw_texture,
130 unsigned face,
131 unsigned level,
132 unsigned zslice )
133 {
134 #if 0
135 /* XXX: what about IDGNG?
136 */
137 if (!BRW_IS_G4X(brw->brw_screen->pci_id))
138 {
139 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
140 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
141
142 /* The original gen4 hardware couldn't set up WM surfaces pointing
143 * at an offset within a tile, which can happen when rendering to
144 * anything but the base level of a texture or the +X face/0 depth.
145 * This was fixed with the 4 Series hardware.
146 *
147 * For these original chips, you would have to make the depth and
148 * color destination surfaces include information on the texture
149 * type, LOD, face, and various limits to use them as a destination.
150 *
151 * This is easy in Gallium as surfaces are all backed by
152 * textures, but there's also a nasty requirement that the depth
153 * and the color surfaces all be of the same LOD, which is
154 * harder to get around as we can't look at a surface in
155 * isolation and decide if it's legal.
156 *
157 * Instead, end up being pessimistic and say that for i965,
158 * ... ??
159 */
160 if (brw_tex->tiling != I915_TILING_NONE &&
161 (brw_tex_image_offset(brw_tex, face, level, zslize) & 4095)) {
162 if (BRW_DEBUG & DEBUG_VIEW)
163 debug_printf("%s: need surface view for non-aligned tex image\n",
164 __FUNCTION__);
165 return GL_TRUE;
166 }
167 }
168 #endif
169
170 /* Tiled 3d textures don't have subsets that look like 2d surfaces:
171 */
172
173 /* Everything else should be fine to render to in-place:
174 */
175 return GL_FALSE;
176 }
177
178 /* Look at all texture views and figure out if any of them need to be
179 * back-copied into the texture for sampling
180 */
181 void brw_update_texture( struct pipe_screen *screen,
182 struct pipe_texture *texture )
183 {
184 /* currently nothing to do */
185 }
186
187
188 static struct pipe_surface *create_linear_view( struct brw_screen *brw_screen,
189 struct brw_texture *brw_tex,
190 struct brw_surface_id id )
191 {
192
193 }
194
195 static struct pipe_surface *create_in_place_view( struct brw_screen *brw_screen,
196 struct brw_texture *brw_tex,
197 struct brw_surface_id id )
198 {
199 struct brw_surface *surface = CALLOC_STRUCT(brw_surface);
200 surface->id = id;
201
202 }
203
204 /* Get a surface which is view into a texture
205 */
206 struct pipe_surface *brw_get_tex_surface(struct pipe_screen *screen,
207 struct pipe_texture *texture,
208 unsigned face, unsigned level,
209 unsigned zslice,
210 unsigned usage )
211 {
212 struct brw_screen *bscreen = brw_screen(screen);
213 struct brw_surface_id id;
214
215 id.face = face;
216 id.level = level;
217 id.zslice = zslice;
218
219 if (need_linear_view(brw_screen, brw_tex, id))
220 type = BRW_VIEW_LINEAR;
221 else
222 type = BRW_VIEW_IN_PLACE;
223
224
225 foreach (surface, texture->views[type]) {
226 if (id.value == surface->id.value)
227 return surface;
228 }
229
230 switch (type) {
231 case BRW_VIEW_LINEAR:
232 surface = create_linear_view( texture, id, type );
233 break;
234 case BRW_VIEW_IN_PLACE:
235 surface = create_in_place_view( texture, id, type );
236 break;
237 default:
238 return NULL;
239 }
240
241 insert_at_head( texture->views[type], surface );
242 return surface;
243 }
244
245
246 void brw_tex_surface_destroy( struct pipe_surface *surface )
247 {
248 }