i965: Use unreachable() instead of unconditional assert().
[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 * Create the constant buffer surface. Vertex/fragment shader constants will be
270 * read from this buffer with Data Port Read instructions/messages.
271 */
272 static void
273 gen8_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
274 {
275 struct gl_context *ctx = &brw->ctx;
276
277 /* _NEW_BUFFERS */
278 const struct gl_framebuffer *fb = ctx->DrawBuffer;
279 uint32_t surf_index =
280 brw->wm.prog_data->binding_table.render_target_start + unit;
281
282 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 13 * 4, 64,
283 &brw->wm.base.surf_offset[surf_index]);
284 memset(surf, 0, 13 * 4);
285
286 surf[0] = BRW_SURFACE_NULL << BRW_SURFACE_TYPE_SHIFT |
287 BRW_SURFACEFORMAT_B8G8R8A8_UNORM << BRW_SURFACE_FORMAT_SHIFT |
288 GEN8_SURFACE_TILING_Y;
289 surf[2] = SET_FIELD(fb->Width - 1, GEN7_SURFACE_WIDTH) |
290 SET_FIELD(fb->Height - 1, GEN7_SURFACE_HEIGHT);
291 }
292
293 /**
294 * Sets up a surface state structure to point at the given region.
295 * While it is only used for the front/back buffer currently, it should be
296 * usable for further buffers when doing ARB_draw_buffer support.
297 */
298 static void
299 gen8_update_renderbuffer_surface(struct brw_context *brw,
300 struct gl_renderbuffer *rb,
301 bool layered,
302 unsigned unit)
303 {
304 struct gl_context *ctx = &brw->ctx;
305 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
306 struct intel_mipmap_tree *mt = irb->mt;
307 struct intel_mipmap_tree *aux_mt = NULL;
308 uint32_t aux_mode = 0;
309 unsigned width = mt->logical_width0;
310 unsigned height = mt->logical_height0;
311 unsigned pitch = mt->pitch;
312 uint32_t tiling = mt->tiling;
313 uint32_t format = 0;
314 uint32_t surf_type;
315 bool is_array = false;
316 int depth = MAX2(irb->layer_count, 1);
317 const int min_array_element = (mt->format == MESA_FORMAT_S_UINT8) ?
318 irb->mt_layer : (irb->mt_layer / MAX2(mt->num_samples, 1));
319 GLenum gl_target =
320 rb->TexImage ? rb->TexImage->TexObject->Target : GL_TEXTURE_2D;
321
322 uint32_t surf_index =
323 brw->wm.prog_data->binding_table.render_target_start + unit;
324
325 intel_miptree_used_for_rendering(mt);
326
327 switch (gl_target) {
328 case GL_TEXTURE_CUBE_MAP_ARRAY:
329 case GL_TEXTURE_CUBE_MAP:
330 surf_type = BRW_SURFACE_2D;
331 is_array = true;
332 depth *= 6;
333 break;
334 case GL_TEXTURE_3D:
335 depth = MAX2(irb->mt->logical_depth0, 1);
336 /* fallthrough */
337 default:
338 surf_type = translate_tex_target(gl_target);
339 is_array = _mesa_tex_target_is_array(gl_target);
340 break;
341 }
342
343 /* _NEW_BUFFERS */
344 /* Render targets can't use IMS layout. Stencil in turn gets configured as
345 * single sampled and indexed manually by the program.
346 */
347 if (mt->format == MESA_FORMAT_S_UINT8) {
348 brw_configure_w_tiled(mt, true, &width, &height, &pitch,
349 &tiling, &format);
350 } else {
351 assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
352 assert(brw_render_target_supported(brw, rb));
353 mesa_format rb_format = _mesa_get_render_format(ctx,
354 intel_rb_format(irb));
355 format = brw->render_target_format[rb_format];
356 if (unlikely(!brw->format_supported_as_render_target[rb_format]))
357 _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
358 __FUNCTION__, _mesa_get_format_name(rb_format));
359 }
360
361 if (mt->mcs_mt) {
362 aux_mt = mt->mcs_mt;
363 aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
364 }
365
366 uint32_t *surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 13 * 4, 64,
367 &brw->wm.base.surf_offset[surf_index]);
368
369 surf[0] = (surf_type << BRW_SURFACE_TYPE_SHIFT) |
370 (is_array ? GEN7_SURFACE_IS_ARRAY : 0) |
371 (format << BRW_SURFACE_FORMAT_SHIFT) |
372 vertical_alignment(mt) |
373 horizontal_alignment(mt) |
374 surface_tiling_mode(tiling);
375
376 surf[1] = SET_FIELD(BDW_MOCS_WT, GEN8_SURFACE_MOCS) | mt->qpitch >> 2;
377
378 surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
379 SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
380
381 surf[3] = (depth - 1) << BRW_SURFACE_DEPTH_SHIFT |
382 (pitch - 1); /* Surface Pitch */
383
384 surf[4] = min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
385 (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;
386
387 if (mt->format != MESA_FORMAT_S_UINT8)
388 surf[4] |= gen7_surface_msaa_bits(mt->num_samples, mt->msaa_layout);
389
390 surf[5] = irb->mt_level - irb->mt->first_level;
391
392 if (aux_mt) {
393 surf[6] = SET_FIELD(mt->qpitch / 4, GEN8_SURFACE_AUX_QPITCH) |
394 SET_FIELD((aux_mt->pitch / 128) - 1, GEN8_SURFACE_AUX_PITCH) |
395 aux_mode;
396 } else {
397 surf[6] = 0;
398 }
399
400 surf[7] = mt->fast_clear_color_value |
401 SET_FIELD(HSW_SCS_RED, GEN7_SURFACE_SCS_R) |
402 SET_FIELD(HSW_SCS_GREEN, GEN7_SURFACE_SCS_G) |
403 SET_FIELD(HSW_SCS_BLUE, GEN7_SURFACE_SCS_B) |
404 SET_FIELD(HSW_SCS_ALPHA, GEN7_SURFACE_SCS_A);
405
406 *((uint64_t *) &surf[8]) = mt->bo->offset64; /* reloc */
407
408 if (aux_mt) {
409 *((uint64_t *) &surf[10]) = aux_mt->bo->offset64;
410 drm_intel_bo_emit_reloc(brw->batch.bo,
411 brw->wm.base.surf_offset[surf_index] + 10 * 4,
412 aux_mt->bo, 0,
413 I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
414 } else {
415 surf[10] = 0;
416 surf[11] = 0;
417 }
418 surf[12] = 0;
419
420 drm_intel_bo_emit_reloc(brw->batch.bo,
421 brw->wm.base.surf_offset[surf_index] + 8 * 4,
422 mt->bo,
423 0,
424 I915_GEM_DOMAIN_RENDER,
425 I915_GEM_DOMAIN_RENDER);
426 }
427
428 void
429 gen8_init_vtable_surface_functions(struct brw_context *brw)
430 {
431 brw->vtbl.update_texture_surface = gen8_update_texture_surface;
432 brw->vtbl.update_renderbuffer_surface = gen8_update_renderbuffer_surface;
433 brw->vtbl.update_null_renderbuffer_surface =
434 gen8_update_null_renderbuffer_surface;
435 brw->vtbl.create_raw_surface = gen8_create_raw_surface;
436 brw->vtbl.emit_buffer_surface_state = gen8_emit_buffer_surface_state;
437 }