OSDN Git Service

i965/meta: Use internal functions for renderbuffer access
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / brw_meta_stencil_blit.c
1 /*
2  * Copyright © 2014 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 /**
25  * @file brw_meta_stencil_blit.c
26  *
27  * Implements upsampling, downsampling and scaling of stencil miptrees. The
28  * logic can be originally found in brw_blorp_blit.c.
29  * Implementation creates a temporary draw framebuffer object and attaches the
30  * destination stencil buffer attachment as color attachment. Source attachment
31  * is in turn treated as a stencil texture and the glsl program used for the
32  * blitting samples it using stencil-indexing.
33  *
34  * Unfortunately as the data port does not support interleaved msaa-surfaces
35  * (stencil is always IMS), the glsl program needs to handle the writing of
36  * individual samples manually. Surface is configured as if it were single
37  * sampled (with adjusted dimensions) and the glsl program extracts the
38  * sample indices from the input coordinates for correct texturing.
39  *
40  * Target surface is also configured as Y-tiled instead of W-tiled in order
41  * to support generations 6-7. Later hardware supports W-tiled as render target
42  * and the logic here could be simplified for those.
43  */
44
45 #include "brw_context.h"
46 #include "intel_batchbuffer.h"
47 #include "intel_fbo.h"
48
49 #include "main/blit.h"
50 #include "main/buffers.h"
51 #include "main/fbobject.h"
52 #include "main/uniforms.h"
53 #include "main/texparam.h"
54 #include "main/texobj.h"
55 #include "main/viewport.h"
56 #include "main/enable.h"
57 #include "main/blend.h"
58 #include "main/varray.h"
59 #include "main/shaderapi.h"
60 #include "util/ralloc.h"
61
62 #include "drivers/common/meta.h"
63 #include "brw_meta_util.h"
64
65 #define FILE_DEBUG_FLAG DEBUG_FBO
66
67 struct blit_dims {
68    int src_x0, src_y0, src_x1, src_y1;
69    int dst_x0, dst_y0, dst_x1, dst_y1;
70    bool mirror_x, mirror_y;
71 };
72
73 static const char *vs_source =
74    "#version 130\n"
75    "in vec2 position;\n"
76    "out vec2 tex_coords;\n"
77    "void main()\n"
78    "{\n"
79    "   tex_coords = (position + 1.0) / 2.0;\n"
80    "   gl_Position = vec4(position, 0.0, 1.0);\n"
81    "}\n";
82
83 static const struct sampler_and_fetch {
84   const char *sampler;
85   const char *fetch;
86 } samplers[] = {
87    { "uniform usampler2D texSampler;\n",
88      "   out_color = texelFetch(texSampler, txl_coords, 0)" },
89    { "#extension GL_ARB_texture_multisample : enable\n"
90      "uniform usampler2DMS texSampler;\n",
91      "   out_color = texelFetch(texSampler, txl_coords, sample_index)" }
92 };
93
94 /**
95  * Translating Y-tiled to W-tiled:
96  *
97  *  X' = (X & ~0b1011) >> 1 | (Y & 0b1) << 2 | X & 0b1
98  *  Y' = (Y & ~0b1) << 1 | (X & 0b1000) >> 2 | (X & 0b10) >> 1
99  */
100 static const char *fs_tmpl =
101    "#version 130\n"
102    "%s"
103    "uniform float src_x_scale;\n"
104    "uniform float src_y_scale;\n"
105    "uniform float src_x_off;\n" /* Top right coordinates of the source */
106    "uniform float src_y_off;\n" /* rectangle in W-tiled space. */
107    "uniform float dst_x_off;\n" /* Top right coordinates of the target */
108    "uniform float dst_y_off;\n" /* rectangle in Y-tiled space. */
109    "uniform float draw_rect_w;\n" /* This is the unnormalized size of the */
110    "uniform float draw_rect_h;\n" /* drawing rectangle in Y-tiled space. */
111    "uniform int dst_x0;\n" /* This is the bounding rectangle in the W-tiled */
112    "uniform int dst_x1;\n" /* space that will be used to skip pixels lying */
113    "uniform int dst_y0;\n" /* outside. In some cases the Y-tiled rectangle */
114    "uniform int dst_y1;\n" /* is larger. */
115    "uniform int dst_num_samples;\n"
116    "in vec2 tex_coords;\n"
117    "ivec2 txl_coords;\n"
118    "int sample_index;\n"
119    "out uvec4 out_color;\n"
120    "\n"
121    "void get_unorm_target_coords()\n"
122    "{\n"
123    "   txl_coords.x = int(tex_coords.x * draw_rect_w + dst_x_off);\n"
124    "   txl_coords.y = int(tex_coords.y * draw_rect_h + dst_y_off);\n"
125    "}\n"
126    "\n"
127    "void translate_dst_to_src()\n"
128    "{\n"
129    "   txl_coords.x = int(float(txl_coords.x) * src_x_scale + src_x_off);\n"
130    "   txl_coords.y = int(float(txl_coords.y) * src_y_scale + src_y_off);\n"
131    "}\n"
132    "\n"
133    "void translate_y_to_w_tiling()\n"
134    "{\n"
135    "   int X = txl_coords.x;\n"
136    "   int Y = txl_coords.y;\n"
137    "   txl_coords.x = (X & int(0xfff4)) >> 1;\n"
138    "   txl_coords.x |= ((Y & int(0x1)) << 2);\n"
139    "   txl_coords.x |= (X & int(0x1));\n"
140    "   txl_coords.y = (Y & int(0xfffe)) << 1;\n"
141    "   txl_coords.y |= ((X & int(0x8)) >> 2);\n"
142    "   txl_coords.y |= ((X & int(0x2)) >> 1);\n"
143    "}\n"
144    "\n"
145    "void decode_msaa()\n"
146    "{\n"
147    "   int X = txl_coords.x;\n"
148    "   int Y = txl_coords.y;\n"
149    "   switch (dst_num_samples) {\n"
150    "   case 0:\n"
151    "      sample_index = 0;\n"
152    "      break;\n"
153    "   case 2:\n"
154    "      txl_coords.x = ((X & int(0xfffc)) >> 1) | (X & int(0x1));\n"
155    "      sample_index = (X & 0x2) >> 1;\n"
156    "      break;\n"
157    "   case 4:\n"
158    "      txl_coords.x = ((X & int(0xfffc)) >> 1) | (X & int(0x1));\n"
159    "      txl_coords.y = ((Y & int(0xfffc)) >> 1) | (Y & int(0x1));\n"
160    "      sample_index = (Y & 0x2) | ((X & 0x2) >> 1);\n"
161    "      break;\n"
162    "   case 8:\n"
163    "      txl_coords.x = ((X & int(0xfff8)) >> 2) | (X & int(0x1));\n"
164    "      txl_coords.y = ((Y & int(0xfffc)) >> 1) | (Y & int(0x1));\n"
165    "      sample_index = (X & 0x4) | (Y & 0x2) | ((X & 0x2) >> 1);\n"
166    "      break;\n"
167    "   case 16:\n"
168    "      txl_coords.x = ((X & int(0xfff8)) >> 2) | (X & int(0x1));\n"
169    "      txl_coords.y = ((Y & int(0xfff8)) >> 2) | (Y & int(0x1));\n"
170    "      sample_index = (((Y & 0x4) << 1) | (X & 0x4) | (Y & 0x2) |\n"
171    "                      ((X & 0x2) >> 1));\n"
172    "      break;\n"
173    "   }\n"
174    "}\n"
175    "\n"
176    "void discard_outside_bounding_rect()\n"
177    "{\n"
178    "   int X = txl_coords.x;\n"
179    "   int Y = txl_coords.y;\n"
180    "   if (X >= dst_x1 || X < dst_x0 || Y >= dst_y1 || Y < dst_y0)\n"
181    "      discard;\n"
182    "}\n"
183    "\n"
184    "void main()\n"
185    "{\n"
186    "   get_unorm_target_coords();\n"
187    "   translate_y_to_w_tiling();\n"
188    "   decode_msaa();"
189    "   discard_outside_bounding_rect();\n"
190    "   translate_dst_to_src();\n"
191    "   %s;\n"
192    "}\n";
193
194 /**
195  * Setup uniforms telling the coordinates of the destination rectangle in the
196  * native w-tiled space. These are needed to ignore pixels that lie outside.
197  * The destination is drawn as Y-tiled and in some cases the Y-tiled drawing
198  * rectangle is larger than the original (for example 1x4 w-tiled requires
199  * 16x2 y-tiled).
200  */
201 static void
202 setup_bounding_rect(GLuint prog, const struct blit_dims *dims)
203 {
204    _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_x0"), dims->dst_x0);
205    _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_x1"), dims->dst_x1);
206    _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_y0"), dims->dst_y0);
207    _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_y1"), dims->dst_y1);
208 }
209
210 /**
211  * Setup uniforms telling the destination width, height and the offset. These
212  * are needed to unnormalize the input coordinates and to correctly translate
213  * between destination and source that may have differing offsets.
214  */
215 static void
216 setup_drawing_rect(GLuint prog, const struct blit_dims *dims)
217 {
218    _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "draw_rect_w"),
219                    dims->dst_x1 - dims->dst_x0);
220    _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "draw_rect_h"),
221                    dims->dst_y1 - dims->dst_y0);
222    _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "dst_x_off"), dims->dst_x0);
223    _mesa_Uniform1f(_mesa_GetUniformLocation(prog, "dst_y_off"), dims->dst_y0);
224 }
225
226 /**
227  * When not mirroring a coordinate (say, X), we need:
228  *   src_x - src_x0 = (dst_x - dst_x0 + 0.5) * scale
229  * Therefore:
230  *   src_x = src_x0 + (dst_x - dst_x0 + 0.5) * scale
231  *
232  * The program uses "round toward zero" to convert the transformed floating
233  * point coordinates to integer coordinates, whereas the behaviour we actually
234  * want is "round to nearest", so 0.5 provides the necessary correction.
235  *
236  * When mirroring X we need:
237  *   src_x - src_x0 = dst_x1 - dst_x - 0.5
238  * Therefore:
239  *   src_x = src_x0 + (dst_x1 -dst_x - 0.5) * scale
240  */
241 static void
242 setup_coord_coeff(GLuint prog, GLuint multiplier, GLuint offset,
243                   int src_0, int src_1, int dst_0, int dst_1, bool mirror)
244 {
245    const float scale = ((float)(src_1 - src_0)) / (dst_1 - dst_0);
246
247    if (mirror) {
248       _mesa_Uniform1f(multiplier, -scale);
249       _mesa_Uniform1f(offset, src_0 + (dst_1 - 0.5f) * scale);
250    } else {
251       _mesa_Uniform1f(multiplier, scale);
252       _mesa_Uniform1f(offset, src_0 + (-dst_0 + 0.5f) * scale);
253    }
254 }
255
256 /**
257  * Setup uniforms providing relation between source and destination surfaces.
258  * Destination coordinates are in Y-tiling layout while texelFetch() expects
259  * W-tiled coordinates. Once the destination coordinates are re-interpreted by
260  * the program into the original W-tiled layout, the program needs to know the
261  * offset and scaling factors between the destination and source.
262  * Note that these are calculated in the original W-tiled space before the
263  * destination rectangle is adjusted for possible msaa and Y-tiling.
264  */
265 static void
266 setup_coord_transform(GLuint prog, const struct blit_dims *dims)
267 {
268    setup_coord_coeff(prog,
269                      _mesa_GetUniformLocation(prog, "src_x_scale"),
270                      _mesa_GetUniformLocation(prog, "src_x_off"),
271                      dims->src_x0, dims->src_x1, dims->dst_x0, dims->dst_x1,
272                      dims->mirror_x);
273
274    setup_coord_coeff(prog,
275                      _mesa_GetUniformLocation(prog, "src_y_scale"),
276                      _mesa_GetUniformLocation(prog, "src_y_off"),
277                      dims->src_y0, dims->src_y1, dims->dst_y0, dims->dst_y1,
278                      dims->mirror_y);
279 }
280
281 static GLuint
282 setup_program(struct brw_context *brw, bool msaa_tex)
283 {
284    struct gl_context *ctx = &brw->ctx;
285    struct blit_state *blit = &ctx->Meta->Blit;
286    char *fs_source;
287    const struct sampler_and_fetch *sampler = &samplers[msaa_tex];
288
289    _mesa_meta_setup_vertex_objects(&brw->ctx, &blit->VAO, &blit->buf_obj, true,
290                                    2, 2, 0);
291
292    GLuint *prog_id = &brw->meta_stencil_blit_programs[msaa_tex];
293
294    if (*prog_id) {
295       _mesa_UseProgram(*prog_id);
296       return *prog_id;
297    }
298
299    fs_source = ralloc_asprintf(NULL, fs_tmpl, sampler->sampler,
300                                sampler->fetch);
301    _mesa_meta_compile_and_link_program(ctx, vs_source, fs_source,
302                                        "i965 stencil blit",
303                                        prog_id);
304    ralloc_free(fs_source);
305
306    return *prog_id;
307 }
308
309 /**
310  * Samples in stencil buffer are interleaved, and unfortunately the data port
311  * does not support it as render target. Therefore the surface is set up as
312  * single sampled and the program handles the interleaving.
313  * In case of single sampled stencil, the render buffer is adjusted with
314  * twice the base level height in order for the program to be able to write
315  * any mip-level. (Used to set the drawing rectangle for the hw).
316  */
317 static void
318 adjust_msaa(struct blit_dims *dims, int num_samples)
319 {
320    if (num_samples == 2) {
321       dims->dst_x0 *= 2;
322       dims->dst_x1 *= 2;
323    } else if (num_samples) {
324       const int y_num_samples = num_samples >= 16 ? 4 : 2;
325       const int x_num_samples = num_samples / y_num_samples;
326       dims->dst_x0 = ROUND_DOWN_TO(dims->dst_x0 * x_num_samples,
327                                    x_num_samples * 2);
328       dims->dst_y0 = ROUND_DOWN_TO(dims->dst_y0 * y_num_samples,
329                                    y_num_samples * 2);
330       dims->dst_x1 = ALIGN(dims->dst_x1 * x_num_samples,
331                            x_num_samples * 2);
332       dims->dst_y1 = ALIGN(dims->dst_y1 * y_num_samples,
333                            y_num_samples * 2);
334    }
335 }
336
337 /**
338  * Stencil is mapped as Y-tiled render target and the dimensions need to be
339  * adjusted in order for the Y-tiled rectangle to cover the entire linear
340  * memory space of the original W-tiled rectangle.
341  */
342 static void
343 adjust_tiling(struct blit_dims *dims, int num_samples)
344 {
345    const unsigned x_align = 8, y_align = num_samples > 2 ? 8 : 4;
346
347    dims->dst_x0 = ROUND_DOWN_TO(dims->dst_x0, x_align) * 2;
348    dims->dst_y0 = ROUND_DOWN_TO(dims->dst_y0, y_align) / 2;
349    dims->dst_x1 = ALIGN(dims->dst_x1, x_align) * 2;
350    dims->dst_y1 = ALIGN(dims->dst_y1, y_align) / 2;
351 }
352
353 /**
354  * When stencil is mapped as Y-tiled render target the mip-level offsets
355  * calculated for the Y-tiling do not always match the offsets in W-tiling.
356  * Therefore the sampling engine cannot be used for individual mip-level
357  * access but the program needs to do it internally. This can be achieved
358  * by shifting the coordinates of the blit rectangle here.
359  */
360 static void
361 adjust_mip_level(const struct intel_mipmap_tree *mt,
362                  unsigned level, unsigned layer, struct blit_dims *dims)
363 {
364    unsigned x_offset;
365    unsigned y_offset;
366
367    intel_miptree_get_image_offset(mt, level, layer, &x_offset, &y_offset);
368
369    dims->dst_x0 += x_offset;
370    dims->dst_y0 += y_offset;
371    dims->dst_x1 += x_offset;
372    dims->dst_y1 += y_offset;
373 }
374
375 static void
376 prepare_vertex_data(struct gl_context *ctx, struct gl_buffer_object *buf_obj)
377 {
378    static const struct vertex verts[] = {
379       { .x = -1.0f, .y = -1.0f },
380       { .x =  1.0f, .y = -1.0f },
381       { .x =  1.0f, .y =  1.0f },
382       { .x = -1.0f, .y =  1.0f } };
383
384    _mesa_buffer_sub_data(ctx, buf_obj, 0, sizeof(verts), verts, __func__);
385 }
386
387 static bool
388 set_read_rb_tex_image(struct gl_context *ctx, struct fb_tex_blit_state *blit,
389                       GLenum *target)
390 {
391    const struct gl_renderbuffer_attachment *att =
392       &ctx->ReadBuffer->Attachment[BUFFER_STENCIL];
393    struct gl_renderbuffer *rb = att->Renderbuffer;
394    struct gl_texture_object *tex_obj;
395    unsigned level = 0;
396
397    /* If the renderbuffer is already backed by an tex image, use it. */
398    if (att->Texture) {
399       tex_obj = att->Texture;
400       *target = tex_obj->Target;
401       level = att->TextureLevel;
402    } else {
403       if (!_mesa_meta_bind_rb_as_tex_image(ctx, rb, &blit->tempTex, &tex_obj,
404                                           target)) {
405          return false;
406       }
407    }
408
409    blit->baseLevelSave = tex_obj->BaseLevel;
410    blit->maxLevelSave = tex_obj->MaxLevel;
411    blit->stencilSamplingSave = tex_obj->StencilSampling;
412    blit->samp_obj = _mesa_meta_setup_sampler(ctx, tex_obj, *target,
413                                              GL_NEAREST, level);
414    return true;
415 }
416
417 static void
418 brw_meta_stencil_blit(struct brw_context *brw,
419                       struct intel_mipmap_tree *dst_mt,
420                       unsigned dst_level, unsigned dst_layer,
421                       const struct blit_dims *orig_dims)
422 {
423    struct gl_context *ctx = &brw->ctx;
424    struct blit_dims dims = *orig_dims;
425    struct fb_tex_blit_state blit;
426    GLuint prog, fbo;
427    struct gl_renderbuffer *rb;
428    GLenum target;
429
430    _mesa_meta_fb_tex_blit_begin(ctx, &blit);
431    /* XXX: Pretend to support stencil textures so _mesa_base_tex_format()
432     * returns a valid format.  When we properly support the extension, we
433     * should remove this.
434     */
435    assert(ctx->Extensions.ARB_texture_stencil8 == false);
436    ctx->Extensions.ARB_texture_stencil8 = true;
437
438    _mesa_GenFramebuffers(1, &fbo);
439    /* Force the surface to be configured for level zero. */
440    rb = brw_get_rb_for_slice(brw, dst_mt, 0, dst_layer, true);
441    adjust_msaa(&dims, dst_mt->num_samples);
442    adjust_tiling(&dims, dst_mt->num_samples);
443
444    _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
445    _mesa_framebuffer_renderbuffer(ctx, ctx->DrawBuffer, GL_COLOR_ATTACHMENT0,
446                                   rb);
447    _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);
448    ctx->DrawBuffer->_Status = GL_FRAMEBUFFER_COMPLETE;
449
450    if (!set_read_rb_tex_image(ctx, &blit, &target)) {
451       goto error;
452    }
453
454    _mesa_TexParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE,
455                        GL_STENCIL_INDEX);
456
457    prog = setup_program(brw, target != GL_TEXTURE_2D);
458    setup_bounding_rect(prog, orig_dims);
459    setup_drawing_rect(prog, &dims);
460    setup_coord_transform(prog, orig_dims);
461
462    _mesa_Uniform1i(_mesa_GetUniformLocation(prog, "dst_num_samples"),
463                    dst_mt->num_samples);
464
465    prepare_vertex_data(ctx, ctx->Meta->Blit.buf_obj);
466    _mesa_set_viewport(ctx, 0, dims.dst_x0, dims.dst_y0,
467                       dims.dst_x1 - dims.dst_x0, dims.dst_y1 - dims.dst_y0);
468    _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
469    _mesa_set_enable(ctx, GL_DEPTH_TEST, false);
470
471    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
472
473 error:
474    ctx->Extensions.ARB_texture_stencil8 = false;
475    _mesa_meta_fb_tex_blit_end(ctx, target, &blit);
476    _mesa_meta_end(ctx);
477
478    _mesa_DeleteRenderbuffers(1, &rb->Name);
479    _mesa_DeleteFramebuffers(1, &fbo);
480 }
481
482 void
483 brw_meta_fbo_stencil_blit(struct brw_context *brw,
484                           struct gl_framebuffer *read_fb,
485                           struct gl_framebuffer *draw_fb,
486                           GLfloat src_x0, GLfloat src_y0,
487                           GLfloat src_x1, GLfloat src_y1,
488                           GLfloat dst_x0, GLfloat dst_y0,
489                           GLfloat dst_x1, GLfloat dst_y1)
490 {
491    struct gl_context *ctx = &brw->ctx;
492    struct gl_renderbuffer *draw_rb =
493       draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer;
494    const struct intel_renderbuffer *dst_irb = intel_renderbuffer(draw_rb);
495    struct intel_mipmap_tree *dst_mt = dst_irb->mt;
496
497    if (!dst_mt)
498       return;
499
500    if (dst_mt->stencil_mt)
501       dst_mt = dst_mt->stencil_mt;
502
503    bool mirror_x, mirror_y;
504    if (brw_meta_mirror_clip_and_scissor(ctx, read_fb, draw_fb,
505                                         &src_x0, &src_y0, &src_x1, &src_y1,
506                                         &dst_x0, &dst_y0, &dst_x1, &dst_y1,
507                                         &mirror_x, &mirror_y))
508       return;
509
510    struct blit_dims dims = { .src_x0 = src_x0, .src_y0 = src_y0,
511                              .src_x1 = src_x1, .src_y1 = src_y1,
512                              .dst_x0 = dst_x0, .dst_y0 = dst_y0,
513                              .dst_x1 = dst_x1, .dst_y1 = dst_y1,
514                              .mirror_x = mirror_x, .mirror_y = mirror_y };
515    adjust_mip_level(dst_mt, dst_irb->mt_level, dst_irb->mt_layer, &dims);
516
517    brw_emit_mi_flush(brw);
518    _mesa_meta_begin(ctx, MESA_META_ALL);
519    brw_meta_stencil_blit(brw,
520                          dst_mt, dst_irb->mt_level, dst_irb->mt_layer, &dims);
521    brw_emit_mi_flush(brw);
522 }
523
524 void
525 brw_meta_stencil_updownsample(struct brw_context *brw,
526                               struct intel_mipmap_tree *src,
527                               struct intel_mipmap_tree *dst)
528 {
529    struct gl_context *ctx = &brw->ctx;
530    struct blit_dims dims = {
531       .src_x0 = 0, .src_y0 = 0,
532       .src_x1 = src->logical_width0, .src_y1 = src->logical_height0,
533       .dst_x0 = 0, .dst_y0 = 0,
534       .dst_x1 = dst->logical_width0, .dst_y1 = dst->logical_height0,
535       .mirror_x = 0, .mirror_y = 0 };
536    GLuint fbo;
537    struct gl_renderbuffer *rb;
538
539    if (dst->stencil_mt)
540       dst = dst->stencil_mt;
541
542    brw_emit_mi_flush(brw);
543    _mesa_meta_begin(ctx, MESA_META_ALL);
544
545    _mesa_GenFramebuffers(1, &fbo);
546    rb = brw_get_rb_for_slice(brw, src, 0, 0, false);
547
548    _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
549    _mesa_framebuffer_renderbuffer(ctx, ctx->ReadBuffer, GL_STENCIL_ATTACHMENT,
550                                   rb);
551
552    brw_meta_stencil_blit(brw, dst, 0, 0, &dims);
553    brw_emit_mi_flush(brw);
554
555    _mesa_DeleteRenderbuffers(1, &rb->Name);
556    _mesa_DeleteFramebuffers(1, &fbo);
557 }