Merge branch 'xa_branch'
[mesa.git] / src / mesa / drivers / dri / 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
33 #include "main/mtypes.h"
34 #include "main/samplerobj.h"
35 #include "main/texstore.h"
36 #include "program/prog_parameter.h"
37
38 #include "intel_mipmap_tree.h"
39 #include "intel_batchbuffer.h"
40 #include "intel_tex.h"
41 #include "intel_fbo.h"
42
43 #include "brw_context.h"
44 #include "brw_state.h"
45 #include "brw_defines.h"
46 #include "brw_wm.h"
47
48 GLuint
49 translate_tex_target(GLenum target)
50 {
51 switch (target) {
52 case GL_TEXTURE_1D:
53 return BRW_SURFACE_1D;
54
55 case GL_TEXTURE_RECTANGLE_NV:
56 return BRW_SURFACE_2D;
57
58 case GL_TEXTURE_2D:
59 return BRW_SURFACE_2D;
60
61 case GL_TEXTURE_3D:
62 return BRW_SURFACE_3D;
63
64 case GL_TEXTURE_CUBE_MAP:
65 return BRW_SURFACE_CUBE;
66
67 default:
68 assert(0);
69 return 0;
70 }
71 }
72
73 uint32_t
74 brw_format_for_mesa_format(gl_format mesa_format)
75 {
76 static const uint32_t table[MESA_FORMAT_COUNT] =
77 {
78 [MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
79 [MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
80 [MESA_FORMAT_A8] = BRW_SURFACEFORMAT_A8_UNORM,
81 [MESA_FORMAT_AL88] = BRW_SURFACEFORMAT_L8A8_UNORM,
82 [MESA_FORMAT_AL1616] = BRW_SURFACEFORMAT_L16A16_UNORM,
83 [MESA_FORMAT_R8] = BRW_SURFACEFORMAT_R8_UNORM,
84 [MESA_FORMAT_R16] = BRW_SURFACEFORMAT_R16_UNORM,
85 [MESA_FORMAT_RG88] = BRW_SURFACEFORMAT_R8G8_UNORM,
86 [MESA_FORMAT_RG1616] = BRW_SURFACEFORMAT_R16G16_UNORM,
87 [MESA_FORMAT_ARGB8888] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM,
88 [MESA_FORMAT_XRGB8888] = BRW_SURFACEFORMAT_B8G8R8X8_UNORM,
89 [MESA_FORMAT_RGB565] = BRW_SURFACEFORMAT_B5G6R5_UNORM,
90 [MESA_FORMAT_ARGB1555] = BRW_SURFACEFORMAT_B5G5R5A1_UNORM,
91 [MESA_FORMAT_ARGB4444] = BRW_SURFACEFORMAT_B4G4R4A4_UNORM,
92 [MESA_FORMAT_YCBCR_REV] = BRW_SURFACEFORMAT_YCRCB_NORMAL,
93 [MESA_FORMAT_YCBCR] = BRW_SURFACEFORMAT_YCRCB_SWAPUVY,
94 [MESA_FORMAT_RGB_FXT1] = BRW_SURFACEFORMAT_FXT1,
95 [MESA_FORMAT_RGBA_FXT1] = BRW_SURFACEFORMAT_FXT1,
96 [MESA_FORMAT_RGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB,
97 [MESA_FORMAT_RGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM,
98 [MESA_FORMAT_RGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM,
99 [MESA_FORMAT_RGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM,
100 [MESA_FORMAT_SRGB_DXT1] = BRW_SURFACEFORMAT_DXT1_RGB_SRGB,
101 [MESA_FORMAT_SRGBA_DXT1] = BRW_SURFACEFORMAT_BC1_UNORM_SRGB,
102 [MESA_FORMAT_SRGBA_DXT3] = BRW_SURFACEFORMAT_BC2_UNORM_SRGB,
103 [MESA_FORMAT_SRGBA_DXT5] = BRW_SURFACEFORMAT_BC3_UNORM_SRGB,
104 [MESA_FORMAT_SARGB8] = BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB,
105 [MESA_FORMAT_SLA8] = BRW_SURFACEFORMAT_L8A8_UNORM_SRGB,
106 [MESA_FORMAT_SL8] = BRW_SURFACEFORMAT_L8_UNORM_SRGB,
107 [MESA_FORMAT_DUDV8] = BRW_SURFACEFORMAT_R8G8_SNORM,
108 [MESA_FORMAT_SIGNED_R8] = BRW_SURFACEFORMAT_R8_SNORM,
109 [MESA_FORMAT_SIGNED_RG88_REV] = BRW_SURFACEFORMAT_R8G8_SNORM,
110 [MESA_FORMAT_SIGNED_RGBA8888_REV] = BRW_SURFACEFORMAT_R8G8B8A8_SNORM,
111 [MESA_FORMAT_SIGNED_R16] = BRW_SURFACEFORMAT_R16_SNORM,
112 [MESA_FORMAT_SIGNED_GR1616] = BRW_SURFACEFORMAT_R16G16_SNORM,
113 [MESA_FORMAT_RGBA_FLOAT32] = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT,
114 [MESA_FORMAT_RG_FLOAT32] = BRW_SURFACEFORMAT_R32G32_FLOAT,
115 [MESA_FORMAT_R_FLOAT32] = BRW_SURFACEFORMAT_R32_FLOAT,
116 [MESA_FORMAT_INTENSITY_FLOAT32] = BRW_SURFACEFORMAT_I32_FLOAT,
117 [MESA_FORMAT_LUMINANCE_FLOAT32] = BRW_SURFACEFORMAT_L32_FLOAT,
118 [MESA_FORMAT_ALPHA_FLOAT32] = BRW_SURFACEFORMAT_A32_FLOAT,
119 [MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = BRW_SURFACEFORMAT_L32A32_FLOAT,
120 [MESA_FORMAT_RED_RGTC1] = BRW_SURFACEFORMAT_BC4_UNORM,
121 [MESA_FORMAT_SIGNED_RED_RGTC1] = BRW_SURFACEFORMAT_BC4_SNORM,
122 [MESA_FORMAT_RG_RGTC2] = BRW_SURFACEFORMAT_BC5_UNORM,
123 [MESA_FORMAT_SIGNED_RG_RGTC2] = BRW_SURFACEFORMAT_BC5_SNORM,
124 };
125 assert(mesa_format < MESA_FORMAT_COUNT);
126 return table[mesa_format];
127 }
128
129 bool
130 brw_render_target_supported(gl_format format)
131 {
132 /* These are not color render targets like the table holds, but we
133 * ask the question for FBO completeness.
134 */
135 if (format == MESA_FORMAT_S8_Z24 ||
136 format == MESA_FORMAT_X8_Z24 ||
137 format == MESA_FORMAT_S8 ||
138 format == MESA_FORMAT_Z16) {
139 return true;
140 }
141
142 /* The value of this BRW_SURFACEFORMAT is 0, so hardcode it.
143 */
144 if (format == MESA_FORMAT_RGBA_FLOAT32)
145 return true;
146
147 /* Not exactly true, as some of those formats are not renderable.
148 * But at least we know how to translate them.
149 */
150 return brw_format_for_mesa_format(format) != 0;
151 }
152
153 GLuint
154 translate_tex_format(gl_format mesa_format,
155 GLenum internal_format,
156 GLenum depth_mode,
157 GLenum srgb_decode)
158 {
159 switch( mesa_format ) {
160
161 case MESA_FORMAT_Z16:
162 if (depth_mode == GL_INTENSITY)
163 return BRW_SURFACEFORMAT_I16_UNORM;
164 else if (depth_mode == GL_ALPHA)
165 return BRW_SURFACEFORMAT_A16_UNORM;
166 else if (depth_mode == GL_RED)
167 return BRW_SURFACEFORMAT_R16_UNORM;
168 else
169 return BRW_SURFACEFORMAT_L16_UNORM;
170
171 case MESA_FORMAT_S8_Z24:
172 case MESA_FORMAT_X8_Z24:
173 /* XXX: these different surface formats don't seem to
174 * make any difference for shadow sampler/compares.
175 */
176 if (depth_mode == GL_INTENSITY)
177 return BRW_SURFACEFORMAT_I24X8_UNORM;
178 else if (depth_mode == GL_ALPHA)
179 return BRW_SURFACEFORMAT_A24X8_UNORM;
180 else if (depth_mode == GL_RED)
181 return BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS;
182 else
183 return BRW_SURFACEFORMAT_L24X8_UNORM;
184
185 case MESA_FORMAT_SARGB8:
186 case MESA_FORMAT_SLA8:
187 case MESA_FORMAT_SL8:
188 if (srgb_decode == GL_DECODE_EXT)
189 return brw_format_for_mesa_format(mesa_format);
190 else if (srgb_decode == GL_SKIP_DECODE_EXT)
191 return brw_format_for_mesa_format(_mesa_get_srgb_format_linear(mesa_format));
192
193 case MESA_FORMAT_RGBA_FLOAT32:
194 /* The value of this BRW_SURFACEFORMAT is 0, which tricks the
195 * assertion below.
196 */
197 return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
198
199 default:
200 assert(brw_format_for_mesa_format(mesa_format) != 0);
201 return brw_format_for_mesa_format(mesa_format);
202 }
203 }
204
205 static uint32_t
206 brw_get_surface_tiling_bits(uint32_t tiling)
207 {
208 switch (tiling) {
209 case I915_TILING_X:
210 return BRW_SURFACE_TILED;
211 case I915_TILING_Y:
212 return BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y;
213 default:
214 return 0;
215 }
216 }
217
218 static void
219 brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
220 {
221 struct brw_context *brw = brw_context(ctx);
222 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
223 struct intel_texture_object *intelObj = intel_texture_object(tObj);
224 struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
225 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
226 const GLuint surf_index = SURF_INDEX_TEXTURE(unit);
227 uint32_t *surf;
228
229 surf = brw_state_batch(brw, 6 * 4, 32, &brw->wm.surf_offset[surf_index]);
230
231 surf[0] = (translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
232 BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
233 BRW_SURFACE_CUBEFACE_ENABLES |
234 (translate_tex_format(firstImage->TexFormat,
235 firstImage->InternalFormat,
236 sampler->DepthMode,
237 sampler->sRGBDecode) <<
238 BRW_SURFACE_FORMAT_SHIFT));
239
240 surf[1] = intelObj->mt->region->buffer->offset; /* reloc */
241
242 surf[2] = ((intelObj->_MaxLevel - tObj->BaseLevel) << BRW_SURFACE_LOD_SHIFT |
243 (firstImage->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
244 (firstImage->Height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
245
246 surf[3] = (brw_get_surface_tiling_bits(intelObj->mt->region->tiling) |
247 (firstImage->Depth - 1) << BRW_SURFACE_DEPTH_SHIFT |
248 ((intelObj->mt->region->pitch * intelObj->mt->cpp) - 1) <<
249 BRW_SURFACE_PITCH_SHIFT);
250
251 surf[4] = 0;
252 surf[5] = 0;
253
254 /* Emit relocation to surface contents */
255 drm_intel_bo_emit_reloc(brw->intel.batch.bo,
256 brw->wm.surf_offset[surf_index] + 4,
257 intelObj->mt->region->buffer, 0,
258 I915_GEM_DOMAIN_SAMPLER, 0);
259 }
260
261 /**
262 * Create the constant buffer surface. Vertex/fragment shader constants will be
263 * read from this buffer with Data Port Read instructions/messages.
264 */
265 void
266 brw_create_constant_surface(struct brw_context *brw,
267 drm_intel_bo *bo,
268 int width,
269 uint32_t *out_offset)
270 {
271 struct intel_context *intel = &brw->intel;
272 const GLint w = width - 1;
273 uint32_t *surf;
274
275 surf = brw_state_batch(brw, 6 * 4, 32, out_offset);
276
277 surf[0] = (BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
278 BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
279 BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_SURFACE_FORMAT_SHIFT);
280
281 if (intel->gen >= 6)
282 surf[0] |= BRW_SURFACE_RC_READ_WRITE;
283
284 surf[1] = bo->offset; /* reloc */
285
286 surf[2] = (((w & 0x7f) - 1) << BRW_SURFACE_WIDTH_SHIFT |
287 (((w >> 7) & 0x1fff) - 1) << BRW_SURFACE_HEIGHT_SHIFT);
288
289 surf[3] = ((((w >> 20) & 0x7f) - 1) << BRW_SURFACE_DEPTH_SHIFT |
290 (width * 16 - 1) << BRW_SURFACE_PITCH_SHIFT);
291
292 surf[4] = 0;
293 surf[5] = 0;
294
295 /* Emit relocation to surface contents. Section 5.1.1 of the gen4
296 * bspec ("Data Cache") says that the data cache does not exist as
297 * a separate cache and is just the sampler cache.
298 */
299 drm_intel_bo_emit_reloc(brw->intel.batch.bo,
300 *out_offset + 4,
301 bo, 0,
302 I915_GEM_DOMAIN_SAMPLER, 0);
303 }
304
305 /* Creates a new WM constant buffer reflecting the current fragment program's
306 * constants, if needed by the fragment program.
307 *
308 * Otherwise, constants go through the CURBEs using the brw_constant_buffer
309 * state atom.
310 */
311 static void
312 prepare_wm_pull_constants(struct brw_context *brw)
313 {
314 struct gl_context *ctx = &brw->intel.ctx;
315 struct intel_context *intel = &brw->intel;
316 struct brw_fragment_program *fp =
317 (struct brw_fragment_program *) brw->fragment_program;
318 const int size = brw->wm.prog_data->nr_pull_params * sizeof(float);
319 float *constants;
320 unsigned int i;
321
322 _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
323
324 /* BRW_NEW_FRAGMENT_PROGRAM */
325 if (brw->wm.prog_data->nr_pull_params == 0) {
326 if (brw->wm.const_bo) {
327 drm_intel_bo_unreference(brw->wm.const_bo);
328 brw->wm.const_bo = NULL;
329 brw->state.dirty.brw |= BRW_NEW_WM_CONSTBUF;
330 }
331 return;
332 }
333
334 drm_intel_bo_unreference(brw->wm.const_bo);
335 brw->wm.const_bo = drm_intel_bo_alloc(intel->bufmgr, "WM const bo",
336 size, 64);
337
338 /* _NEW_PROGRAM_CONSTANTS */
339 drm_intel_gem_bo_map_gtt(brw->wm.const_bo);
340 constants = brw->wm.const_bo->virtual;
341 for (i = 0; i < brw->wm.prog_data->nr_pull_params; i++) {
342 constants[i] = convert_param(brw->wm.prog_data->pull_param_convert[i],
343 *brw->wm.prog_data->pull_param[i]);
344 }
345 drm_intel_gem_bo_unmap_gtt(brw->wm.const_bo);
346
347 brw->state.dirty.brw |= BRW_NEW_WM_CONSTBUF;
348 }
349
350 const struct brw_tracked_state brw_wm_constants = {
351 .dirty = {
352 .mesa = (_NEW_PROGRAM_CONSTANTS),
353 .brw = (BRW_NEW_FRAGMENT_PROGRAM),
354 .cache = 0
355 },
356 .prepare = prepare_wm_pull_constants,
357 };
358
359 /**
360 * Updates surface / buffer for fragment shader constant buffer, if
361 * one is required.
362 *
363 * This consumes the state updates for the constant buffer, and produces
364 * BRW_NEW_WM_SURFACES to get picked up by brw_prepare_wm_surfaces for
365 * inclusion in the binding table.
366 */
367 static void upload_wm_constant_surface(struct brw_context *brw )
368 {
369 GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
370 struct brw_fragment_program *fp =
371 (struct brw_fragment_program *) brw->fragment_program;
372 const struct gl_program_parameter_list *params =
373 fp->program.Base.Parameters;
374
375 /* If there's no constant buffer, then no surface BO is needed to point at
376 * it.
377 */
378 if (brw->wm.const_bo == 0) {
379 if (brw->wm.surf_offset[surf]) {
380 brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
381 brw->wm.surf_offset[surf] = 0;
382 }
383 return;
384 }
385
386 brw_create_constant_surface(brw, brw->wm.const_bo, params->NumParameters,
387 &brw->wm.surf_offset[surf]);
388 brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
389 }
390
391 const struct brw_tracked_state brw_wm_constant_surface = {
392 .dirty = {
393 .mesa = 0,
394 .brw = (BRW_NEW_WM_CONSTBUF |
395 BRW_NEW_BATCH),
396 .cache = 0
397 },
398 .emit = upload_wm_constant_surface,
399 };
400
401 static void
402 brw_update_null_renderbuffer_surface(struct brw_context *brw, unsigned int unit)
403 {
404 struct intel_context *intel = &brw->intel;
405 uint32_t *surf;
406
407 surf = brw_state_batch(brw, 6 * 4, 32, &brw->wm.surf_offset[unit]);
408
409 surf[0] = (BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
410 BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT);
411 if (intel->gen < 6) {
412 surf[0] |= (1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT |
413 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT |
414 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT |
415 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT);
416 }
417 surf[1] = 0;
418 surf[2] = 0;
419 surf[3] = 0;
420 surf[4] = 0;
421 surf[5] = 0;
422 }
423
424 /**
425 * Sets up a surface state structure to point at the given region.
426 * While it is only used for the front/back buffer currently, it should be
427 * usable for further buffers when doing ARB_draw_buffer support.
428 */
429 static void
430 brw_update_renderbuffer_surface(struct brw_context *brw,
431 struct gl_renderbuffer *rb,
432 unsigned int unit)
433 {
434 struct intel_context *intel = &brw->intel;
435 struct gl_context *ctx = &intel->ctx;
436 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
437 struct intel_region *region = irb->region;
438 uint32_t *surf;
439 uint32_t tile_x, tile_y;
440 uint32_t format = 0;
441
442 surf = brw_state_batch(brw, 6 * 4, 32, &brw->wm.surf_offset[unit]);
443
444 switch (irb->Base.Format) {
445 case MESA_FORMAT_XRGB8888:
446 /* XRGB is handled as ARGB because the chips in this family
447 * cannot render to XRGB targets. This means that we have to
448 * mask writes to alpha (ala glColorMask) and reconfigure the
449 * alpha blending hardware to use GL_ONE (or GL_ZERO) for
450 * cases where GL_DST_ALPHA (or GL_ONE_MINUS_DST_ALPHA) is
451 * used.
452 */
453 format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
454 break;
455 case MESA_FORMAT_INTENSITY_FLOAT32:
456 case MESA_FORMAT_LUMINANCE_FLOAT32:
457 /* For these formats, we just need to read/write the first
458 * channel into R, which is to say that we just treat them as
459 * GL_RED.
460 */
461 format = BRW_SURFACEFORMAT_R32_FLOAT;
462 break;
463 case MESA_FORMAT_SARGB8:
464 /* without GL_EXT_framebuffer_sRGB we shouldn't bind sRGB
465 surfaces to the blend/update as sRGB */
466 if (ctx->Color.sRGBEnabled)
467 format = brw_format_for_mesa_format(irb->Base.Format);
468 else
469 format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
470 break;
471 default:
472 assert(brw_render_target_supported(irb->Base.Format));
473 format = brw_format_for_mesa_format(irb->Base.Format);
474 }
475
476 surf[0] = (BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT |
477 format << BRW_SURFACE_FORMAT_SHIFT);
478
479 /* reloc */
480 surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
481 region->buffer->offset);
482
483 surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
484 (rb->Height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
485
486 surf[3] = (brw_get_surface_tiling_bits(region->tiling) |
487 ((region->pitch * region->cpp) - 1) << BRW_SURFACE_PITCH_SHIFT);
488
489 surf[4] = 0;
490
491 assert(brw->has_surface_tile_offset || (tile_x == 0 && tile_y == 0));
492 /* Note that the low bits of these fields are missing, so
493 * there's the possibility of getting in trouble.
494 */
495 assert(tile_x % 4 == 0);
496 assert(tile_y % 2 == 0);
497 surf[5] = ((tile_x / 4) << BRW_SURFACE_X_OFFSET_SHIFT |
498 (tile_y / 2) << BRW_SURFACE_Y_OFFSET_SHIFT);
499
500 if (intel->gen < 6) {
501 /* _NEW_COLOR */
502 if (!ctx->Color._LogicOpEnabled &&
503 (ctx->Color.BlendEnabled & (1 << unit)))
504 surf[0] |= BRW_SURFACE_BLEND_ENABLED;
505
506 if (!ctx->Color.ColorMask[unit][0])
507 surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_R_SHIFT;
508 if (!ctx->Color.ColorMask[unit][1])
509 surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_G_SHIFT;
510 if (!ctx->Color.ColorMask[unit][2])
511 surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_B_SHIFT;
512
513 /* As mentioned above, disable writes to the alpha component when the
514 * renderbuffer is XRGB.
515 */
516 if (ctx->DrawBuffer->Visual.alphaBits == 0 ||
517 !ctx->Color.ColorMask[unit][3]) {
518 surf[0] |= 1 << BRW_SURFACE_WRITEDISABLE_A_SHIFT;
519 }
520 }
521
522 drm_intel_bo_emit_reloc(brw->intel.batch.bo,
523 brw->wm.surf_offset[unit] + 4,
524 region->buffer,
525 surf[1] - region->buffer->offset,
526 I915_GEM_DOMAIN_RENDER,
527 I915_GEM_DOMAIN_RENDER);
528 }
529
530 static void
531 prepare_wm_surfaces(struct brw_context *brw)
532 {
533 struct gl_context *ctx = &brw->intel.ctx;
534 int i;
535 int nr_surfaces = 0;
536
537 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
538 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
539 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
540 struct intel_region *region = irb ? irb->region : NULL;
541
542 if (region)
543 brw_add_validated_bo(brw, region->buffer);
544 nr_surfaces = SURF_INDEX_DRAW(i) + 1;
545 }
546
547 if (brw->wm.const_bo) {
548 brw_add_validated_bo(brw, brw->wm.const_bo);
549 nr_surfaces = SURF_INDEX_FRAG_CONST_BUFFER + 1;
550 }
551
552 for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
553 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
554
555 if (texUnit->_ReallyEnabled) {
556 struct gl_texture_object *tObj = texUnit->_Current;
557 struct intel_texture_object *intelObj = intel_texture_object(tObj);
558
559 brw_add_validated_bo(brw, intelObj->mt->region->buffer);
560 nr_surfaces = SURF_INDEX_TEXTURE(i) + 1;
561 }
562 }
563
564 /* Have to update this in our prepare, since the unit's prepare
565 * relies on it.
566 */
567 if (brw->wm.nr_surfaces != nr_surfaces) {
568 brw->wm.nr_surfaces = nr_surfaces;
569 brw->state.dirty.brw |= BRW_NEW_NR_WM_SURFACES;
570 }
571 }
572
573 /**
574 * Constructs the set of surface state objects pointed to by the
575 * binding table.
576 */
577 static void
578 upload_wm_surfaces(struct brw_context *brw)
579 {
580 struct gl_context *ctx = &brw->intel.ctx;
581 GLuint i;
582
583 /* _NEW_BUFFERS | _NEW_COLOR */
584 /* Update surfaces for drawing buffers */
585 if (ctx->DrawBuffer->_NumColorDrawBuffers >= 1) {
586 for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
587 if (intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i])) {
588 brw_update_renderbuffer_surface(brw,
589 ctx->DrawBuffer->_ColorDrawBuffers[i],
590 i);
591 } else {
592 brw_update_null_renderbuffer_surface(brw, i);
593 }
594 }
595 } else {
596 brw_update_null_renderbuffer_surface(brw, 0);
597 }
598
599 /* Update surfaces for textures */
600 for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
601 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
602 const GLuint surf = SURF_INDEX_TEXTURE(i);
603
604 /* _NEW_TEXTURE */
605 if (texUnit->_ReallyEnabled) {
606 brw_update_texture_surface(ctx, i);
607 } else {
608 brw->wm.surf_offset[surf] = 0;
609 }
610 }
611
612 brw->state.dirty.brw |= BRW_NEW_WM_SURFACES;
613 }
614
615 const struct brw_tracked_state brw_wm_surfaces = {
616 .dirty = {
617 .mesa = (_NEW_COLOR |
618 _NEW_TEXTURE |
619 _NEW_BUFFERS),
620 .brw = (BRW_NEW_BATCH),
621 .cache = 0
622 },
623 .prepare = prepare_wm_surfaces,
624 .emit = upload_wm_surfaces,
625 };
626
627 /**
628 * Constructs the binding table for the WM surface state, which maps unit
629 * numbers to surface state objects.
630 */
631 static void
632 brw_wm_upload_binding_table(struct brw_context *brw)
633 {
634 uint32_t *bind;
635 int i;
636
637 /* Might want to calculate nr_surfaces first, to avoid taking up so much
638 * space for the binding table.
639 */
640 bind = brw_state_batch(brw, sizeof(uint32_t) * BRW_WM_MAX_SURF,
641 32, &brw->wm.bind_bo_offset);
642
643 for (i = 0; i < BRW_WM_MAX_SURF; i++) {
644 /* BRW_NEW_WM_SURFACES */
645 bind[i] = brw->wm.surf_offset[i];
646 }
647
648 brw->state.dirty.brw |= BRW_NEW_PS_BINDING_TABLE;
649 }
650
651 const struct brw_tracked_state brw_wm_binding_table = {
652 .dirty = {
653 .mesa = 0,
654 .brw = (BRW_NEW_BATCH |
655 BRW_NEW_WM_SURFACES),
656 .cache = 0
657 },
658 .emit = brw_wm_upload_binding_table,
659 };