i965: Add a comment about null renderbuffer surfaces and why they exist.
[mesa.git] / src / mesa / drivers / dri / i965 / gen8_surface_state.c
1 /*
2 * Copyright © 2012 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 #include "main/blend.h"
25 #include "main/mtypes.h"
26 #include "main/samplerobj.h"
27 #include "main/texformat.h"
28 #include "program/prog_parameter.h"
29
30 #include "intel_mipmap_tree.h"
31 #include "intel_batchbuffer.h"
32 #include "intel_tex.h"
33 #include "intel_fbo.h"
34 #include "intel_buffer_objects.h"
35
36 #include "brw_context.h"
37 #include "brw_state.h"
38 #include "brw_defines.h"
39 #include "brw_wm.h"
40
41 static uint32_t
42 surface_tiling_mode(uint32_t tiling)
43 {
44 switch (tiling) {
45 case I915_TILING_X:
46 return GEN8_SURFACE_TILING_X;
47 case I915_TILING_Y:
48 return GEN8_SURFACE_TILING_Y;
49 default:
50 return GEN8_SURFACE_TILING_NONE;
51 }
52 }
53
54 static unsigned
55 vertical_alignment(struct intel_mipmap_tree *mt)
56 {
57 switch (mt->align_h) {
58 case 4:
59 return GEN8_SURFACE_VALIGN_4;
60 case 8:
61 return GEN8_SURFACE_VALIGN_8;
62 case 16:
63 return GEN8_SURFACE_VALIGN_16;
64 default:
65 unreachable("Unsupported vertical surface alignment.");
66 }
67 }
68
69 static unsigned
70 horizontal_alignment(struct intel_mipmap_tree *mt)
71 {
72 switch (mt->align_w) {
73 case 4:
74 return GEN8_SURFACE_HALIGN_4;
75 case 8:
76 return GEN8_SURFACE_HALIGN_8;
77 case 16:
78 return GEN8_SURFACE_HALIGN_16;
79 default:
80 unreachable("Unsupported horizontal surface alignment.");
81 }
82 }
83
84 static void
85 gen8_emit_buffer_surface_state(struct brw_context *brw,
86 uint32_t *out_offset,
87 drm_intel_bo *bo,
88 unsigned buffer_offset,
89 unsigned surface_format,
90 unsigned buffer_size,
91 unsigned pitch,
92 unsigned mocs,
93 bool rw)
94 {
95 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
96 13 * 4, 64, out_offset);
97 memset(surf, 0, 13 * 4);
98
99 surf[0] = BRW_SURFACE_BUFFER << BRW_SURFACE_TYPE_SHIFT |
100 surface_format << BRW_SURFACE_FORMAT_SHIFT |
101 BRW_SURFACE_RC_READ_WRITE;
102 surf[1] = SET_FIELD(mocs, GEN8_SURFACE_MOCS);
103
104 surf[2] = SET_FIELD((buffer_size - 1) & 0x7f, GEN7_SURFACE_WIDTH) |
105 SET_FIELD(((buffer_size - 1) >> 7) & 0x3fff, GEN7_SURFACE_HEIGHT);
106 surf[3] = SET_FIELD(((buffer_size - 1) >> 21) & 0x3f, BRW_SURFACE_DEPTH) |
107 (pitch - 1);
108 surf[7] = SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
109 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
110 SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
111 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
112 /* reloc */
113 *((uint64_t *) &surf[8]) = (bo ? bo->offset64 : 0) + buffer_offset;
114
115 /* Emit relocation to surface contents. */
116 if (bo) {
117 drm_intel_bo_emit_reloc(brw->batch.bo, *out_offset + 8 * 4,
118 bo, buffer_offset, I915_GEM_DOMAIN_SAMPLER,
119 rw ? I915_GEM_DOMAIN_SAMPLER : 0);
120 }
121 }
122
123 static void
124 gen8_update_texture_surface(struct gl_context *ctx,
125 unsigned unit,
126 uint32_t *surf_offset,
127 bool for_gather)
128 {
129 struct brw_context *brw = brw_context(ctx);
130 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
131 struct intel_texture_object *intelObj = intel_texture_object(tObj);
132 struct intel_mipmap_tree *mt = intelObj->mt;
133 struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
134 struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
135 struct intel_mipmap_tree *aux_mt = NULL;
136 uint32_t aux_mode = 0;
137 mesa_format format = intelObj->_Format;
138
139 if (tObj->Target == GL_TEXTURE_BUFFER) {
140 brw_update_buffer_texture_surface(ctx, unit, surf_offset);
141 return;
142 }
143
144 if (tObj->StencilSampling && firstImage->_BaseFormat == GL_DEPTH_STENCIL) {
145 mt = mt->stencil_mt;
146 format = MESA_FORMAT_S_UINT8;
147 }
148
149 unsigned tiling_mode, pitch;
150 if (format == MESA_FORMAT_S_UINT8) {
151 tiling_mode = GEN8_SURFACE_TILING_W;
152 pitch = 2 * mt->pitch;
153 } else {
154 tiling_mode = surface_tiling_mode(mt->tiling);
155 pitch = mt->pitch;
156 }
157
158 if (mt->mcs_mt) {
159 aux_mt = mt->mcs_mt;
160 aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
161 }
162
163 /* If this is a view with restricted NumLayers, then our effective depth
164 * is not just the miptree depth.
165 */
166 uint32_t effective_depth =
167 (tObj->Immutable && tObj->Target != GL_TEXTURE_3D) ? tObj->NumLayers
168 : mt->logical_depth0;
169
170 uint32_t tex_format = translate_tex_format(brw, format, sampler->sRGBDecode);
171
172 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
173 13 * 4, 64, surf_offset);
174
175 surf[0] = translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
176 tex_format << BRW_SURFACE_FORMAT_SHIFT |
177 vertical_alignment(mt) |
178 horizontal_alignment(mt) |
179 tiling_mode;
180
181 if (tObj->Target == GL_TEXTURE_CUBE_MAP ||
182 tObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
183 surf[0] |= BRW_SURFACE_CUBEFACE_ENABLES;
184 }
185
186 if (mt->logical_depth0 > 1 && tObj->Target != GL_TEXTURE_3D)
187 surf[0] |= GEN8_SURFACE_IS_ARRAY;
188
189 surf[1] = SET_FIELD(BDW_MOCS_WB, GEN8_SURFACE_MOCS) | mt->qpitch >> 2;
190
191 surf[2] = SET_FIELD(mt->logical_width0 - 1, GEN7_SURFACE_WIDTH) |
192 SET_FIELD(mt->logical_height0 - 1, GEN7_SURFACE_HEIGHT);
193
194 surf[3] = SET_FIELD(effective_depth - 1, BRW_SURFACE_DEPTH) | (pitch - 1);
195
196 surf[4] = gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout) |
197 SET_FIELD(tObj->MinLayer, GEN7_SURFACE_MIN_ARRAY_ELEMENT) |
198 SET_FIELD(effective_depth - 1,
199 GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT);
200
201 surf[5] = SET_FIELD(tObj->MinLevel + tObj->BaseLevel - mt->first_level,
202 GEN7_SURFACE_MIN_LOD) |
203 (intelObj->_MaxLevel - tObj->BaseLevel); /* mip count */
204
205 if (aux_mt) {
206 surf[6] = SET_FIELD(mt->qpitch / 4, GEN8_SURFACE_AUX_QPITCH) |
207 SET_FIELD((aux_mt->pitch / 128) - 1, GEN8_SURFACE_AUX_PITCH) |
208 aux_mode;
209 } else {
210 surf[6] = 0;
211 }
212
213 /* Handling GL_ALPHA as a surface format override breaks 1.30+ style
214 * texturing functions that return a float, as our code generation always
215 * selects the .x channel (which would always be 0).
216 */
217 const bool alpha_depth = tObj->DepthMode == GL_ALPHA &&
218 (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
219 firstImage->_BaseFormat == GL_DEPTH_STENCIL);
220
221 surf[7] = mt->fast_clear_color_value;
222
223 const int swizzle =
224 unlikely(alpha_depth) ? SWIZZLE_XYZW : brw_get_texture_swizzle(ctx, tObj);
225 surf[7] |=
226 SET_FIELD(brw_swizzle_to_scs(GET_SWZ(swizzle, 0), false), GEN7_SURFACE_SCS_R) |
227 SET_FIELD(brw_swizzle_to_scs(GET_SWZ(swizzle, 1), false), GEN7_SURFACE_SCS_G) |
228 SET_FIELD(brw_swizzle_to_scs(GET_SWZ(swizzle, 2), false), GEN7_SURFACE_SCS_B) |
229 SET_FIELD(brw_swizzle_to_scs(GET_SWZ(swizzle, 3), false), GEN7_SURFACE_SCS_A);
230
231 *((uint64_t *) &surf[8]) = mt->bo->offset64 + mt->offset; /* reloc */
232
233 if (aux_mt) {
234 *((uint64_t *) &surf[10]) = aux_mt->bo->offset64;
235 drm_intel_bo_emit_reloc(brw->batch.bo, *surf_offset + 10 * 4,
236 aux_mt->bo, 0,
237 I915_GEM_DOMAIN_SAMPLER, 0);
238 } else {
239 surf[10] = 0;
240 surf[11] = 0;
241 }
242 surf[12] = 0;
243
244 /* Emit relocation to surface contents */
245 drm_intel_bo_emit_reloc(brw->batch.bo,
246 *surf_offset + 8 * 4,
247 mt->bo,
248 mt->offset,
249 I915_GEM_DOMAIN_SAMPLER, 0);
250 }
251
252 static void
253 gen8_create_raw_surface(struct brw_context *brw, drm_intel_bo *bo,
254 uint32_t offset, uint32_t size,
255 uint32_t *out_offset, bool rw)
256 {
257 gen8_emit_buffer_surface_state(brw,
258 out_offset,
259 bo,
260 offset,
261 BRW_SURFACEFORMAT_RAW,
262 size,
263 1,
264 0 /* mocs */,
265 true /* rw */);
266 }
267
268 /**
269 * Creates a null renderbuffer surface.
270 *
271 * This is used when the shader doesn't write to any color output. An FB
272 * write to target 0 will still be emitted, because that's how the thread is
273 * terminated (and computed depth is returned), so we need to have the
274 * hardware discard the target 0 color output..
275 */
276 static void
277 gen8_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
278 {
279 struct gl_context *ctx = &brw->ctx;
280
281 /* _NEW_BUFFERS */
282 const struct gl_framebuffer *fb = ctx->DrawBuffer;
283 uint32_t surf_index =
284 brw->wm.prog_data->binding_table.render_target_start + unit;
285
286 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 13 * 4, 64,
287 &brw->wm.base.surf_offset[surf_index]);
288 memset(surf, 0, 13 * 4);
289
290 surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
291 BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
292 GEN8_SURFACE_TILING_Y;
293 surf[2] = SET_FIELD(fb->Width - 1, GEN7_SURFACE_WIDTH) |
294 SET_FIELD(fb->Height - 1, GEN7_SURFACE_HEIGHT);
295 }
296
297 /**
298 * Sets up a surface state structure to point at the given region.
299 * While it is only used for the front/back buffer currently, it should be
300 * usable for further buffers when doing ARB_draw_buffer support.
301 */
302 static void
303 gen8_update_renderbuffer_surface(struct brw_context *brw,
304 struct gl_renderbuffer *rb,
305 bool layered,
306 unsigned unit)
307 {
308 struct gl_context *ctx = &brw->ctx;
309 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
310 struct intel_mipmap_tree *mt = irb->mt;
311 struct intel_mipmap_tree *aux_mt = NULL;
312 uint32_t aux_mode = 0;
313 unsigned width = mt->logical_width0;
314 unsigned height = mt->logical_height0;
315 unsigned pitch = mt->pitch;
316 uint32_t tiling = mt->tiling;
317 uint32_t format = 0;
318 uint32_t surf_type;
319 bool is_array = false;
320 int depth = MAX2(irb->layer_count, 1);
321 const int min_array_element = (mt->format == MESA_FORMAT_S_UINT8) ?
322 irb->mt_layer : (irb->mt_layer / MAX2(mt->num_samples, 1));
323 GLenum gl_target =
324 rb->TexImage ? rb->TexImage->TexObject->Target : GL_TEXTURE_2D;
325
326 uint32_t surf_index =
327 brw->wm.prog_data->binding_table.render_target_start + unit;
328
329 intel_miptree_used_for_rendering(mt);
330
331 switch (gl_target) {
332 case GL_TEXTURE_CUBE_MAP_ARRAY:
333 case GL_TEXTURE_CUBE_MAP:
334 surf_type = BRW_SURFACE_2D;
335 is_array = true;
336 depth *= 6;
337 break;
338 case GL_TEXTURE_3D:
339 depth = MAX2(irb->mt->logical_depth0, 1);
340 /* fallthrough */
341 default:
342 surf_type = translate_tex_target(gl_target);
343 is_array = _mesa_tex_target_is_array(gl_target);
344 break;
345 }
346
347 /* _NEW_BUFFERS */
348 /* Render targets can't use IMS layout. Stencil in turn gets configured as
349 * single sampled and indexed manually by the program.
350 */
351 if (mt->format == MESA_FORMAT_S_UINT8) {
352 brw_configure_w_tiled(mt, true, &width, &height, &pitch,
353 &tiling, &format);
354 } else {
355 assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
356 assert(brw_render_target_supported(brw, rb));
357 mesa_format rb_format = _mesa_get_render_format(ctx,
358 intel_rb_format(irb));
359 format = brw->render_target_format[rb_format];
360 if (unlikely(!brw->format_supported_as_render_target[rb_format]))
361 _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
362 __FUNCTION__, _mesa_get_format_name(rb_format));
363 }
364
365 if (mt->mcs_mt) {
366 aux_mt = mt->mcs_mt;
367 aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
368 }
369
370 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 13 * 4, 64,
371 &brw->wm.base.surf_offset[surf_index]);
372
373 surf[0] = (surf_type << BRW_SURFACE_TYPE_SHIFT) |
374 (is_array ? GEN7_SURFACE_IS_ARRAY : 0) |
375 (format << BRW_SURFACE_FORMAT_SHIFT) |
376 vertical_alignment(mt) |
377 horizontal_alignment(mt) |
378 surface_tiling_mode(tiling);
379
380 surf[1] = SET_FIELD(BDW_MOCS_WT, GEN8_SURFACE_MOCS) | mt->qpitch >> 2;
381
382 surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
383 SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
384
385 surf[3] = (depth - 1) << BRW_SURFACE_DEPTH_SHIFT |
386 (pitch - 1); /* Surface Pitch */
387
388 surf[4] = min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
389 (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;
390
391 if (mt->format != MESA_FORMAT_S_UINT8)
392 surf[4] |= gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
393
394 surf[5] = irb->mt_level - irb->mt->first_level;
395
396 if (aux_mt) {
397 surf[6] = SET_FIELD(mt->qpitch / 4, GEN8_SURFACE_AUX_QPITCH) |
398 SET_FIELD((aux_mt->pitch / 128) - 1, GEN8_SURFACE_AUX_PITCH) |
399 aux_mode;
400 } else {
401 surf[6] = 0;
402 }
403
404 surf[7] = mt->fast_clear_color_value |
405 SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
406 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
407 SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
408 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
409
410 *((uint64_t *) &surf[8]) = mt->bo->offset64; /* reloc */
411
412 if (aux_mt) {
413 *((uint64_t *) &surf[10]) = aux_mt->bo->offset64;
414 drm_intel_bo_emit_reloc(brw->batch.bo,
415 brw->wm.base.surf_offset[surf_index] + 10 * 4,
416 aux_mt->bo, 0,
417 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
418 } else {
419 surf[10] = 0;
420 surf[11] = 0;
421 }
422 surf[12] = 0;
423
424 drm_intel_bo_emit_reloc(brw->batch.bo,
425 brw->wm.base.surf_offset[surf_index] + 8 * 4,
426 mt->bo,
427 0,
428 I915_GEM_DOMAIN_RENDER,
429 I915_GEM_DOMAIN_RENDER);
430 }
431
432 void
433 gen8_init_vtable_surface_functions(struct brw_context *brw)
434 {
435 brw->vtbl.update_texture_surface = gen8_update_texture_surface;
436 brw->vtbl.update_renderbuffer_surface = gen8_update_renderbuffer_surface;
437 brw->vtbl.update_null_renderbuffer_surface =
438 gen8_update_null_renderbuffer_surface;
439 brw->vtbl.create_raw_surface = gen8_create_raw_surface;
440 brw->vtbl.emit_buffer_surface_state = gen8_emit_buffer_surface_state;
441 }