Clone of mesa.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

brw_meta_stencil_blit.c 19KB

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