Paul Berry | 2c5510b | 2012-04-29 22:00:46 -0700 | [diff] [blame] | 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 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 24 | #include "main/context.h" |
| 25 | #include "main/teximage.h" |
| 26 | #include "main/blend.h" |
| 27 | #include "main/fbobject.h" |
| 28 | #include "main/renderbuffer.h" |
| 29 | #include "main/glformats.h" |
Paul Berry | 2c5510b | 2012-04-29 22:00:46 -0700 | [diff] [blame] | 30 | |
| 31 | #include "brw_blorp.h" |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 32 | #include "brw_context.h" |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 33 | #include "brw_defines.h" |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 34 | #include "brw_meta_util.h" |
Kenneth Graunke | 6f7c41d | 2013-09-30 18:11:03 -0700 | [diff] [blame] | 35 | #include "brw_state.h" |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 36 | #include "intel_fbo.h" |
| 37 | #include "intel_debug.h" |
Paul Berry | 2c5510b | 2012-04-29 22:00:46 -0700 | [diff] [blame] | 38 | |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 39 | #define FILE_DEBUG_FLAG DEBUG_BLORP |
| 40 | |
Jason Ekstrand | 600446c | 2016-08-26 10:07:40 -0700 | [diff] [blame] | 41 | static bool |
| 42 | brw_blorp_lookup_shader(struct blorp_context *blorp, |
| 43 | const void *key, uint32_t key_size, |
| 44 | uint32_t *kernel_out, void *prog_data_out) |
| 45 | { |
| 46 | struct brw_context *brw = blorp->driver_ctx; |
| 47 | return brw_search_cache(&brw->cache, BRW_CACHE_BLORP_PROG, |
| 48 | key, key_size, kernel_out, prog_data_out); |
| 49 | } |
| 50 | |
| 51 | static void |
| 52 | brw_blorp_upload_shader(struct blorp_context *blorp, |
| 53 | const void *key, uint32_t key_size, |
| 54 | const void *kernel, uint32_t kernel_size, |
Jason Ekstrand | 4306c10 | 2016-11-01 14:16:34 -0700 | [diff] [blame] | 55 | const struct brw_stage_prog_data *prog_data, |
| 56 | uint32_t prog_data_size, |
Jason Ekstrand | 600446c | 2016-08-26 10:07:40 -0700 | [diff] [blame] | 57 | uint32_t *kernel_out, void *prog_data_out) |
| 58 | { |
| 59 | struct brw_context *brw = blorp->driver_ctx; |
| 60 | brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG, key, key_size, |
| 61 | kernel, kernel_size, prog_data, prog_data_size, |
| 62 | kernel_out, prog_data_out); |
| 63 | } |
| 64 | |
Jason Ekstrand | a14d1b6 | 2016-08-15 15:07:22 -0700 | [diff] [blame] | 65 | void |
| 66 | brw_blorp_init(struct brw_context *brw) |
| 67 | { |
| 68 | blorp_init(&brw->blorp, brw, &brw->isl_dev); |
Jason Ekstrand | 600446c | 2016-08-26 10:07:40 -0700 | [diff] [blame] | 69 | |
Kenneth Graunke | 9694b23 | 2015-11-30 15:47:13 -0800 | [diff] [blame] | 70 | brw->blorp.compiler = brw->screen->compiler; |
Jason Ekstrand | 99b9e9b | 2016-08-19 00:49:18 -0700 | [diff] [blame] | 71 | |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 72 | switch (brw->gen) { |
| 73 | case 6: |
| 74 | brw->blorp.mocs.tex = 0; |
| 75 | brw->blorp.mocs.rb = 0; |
| 76 | brw->blorp.mocs.vb = 0; |
Jason Ekstrand | bc159ff | 2016-08-18 10:02:03 -0700 | [diff] [blame] | 77 | brw->blorp.exec = gen6_blorp_exec; |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 78 | break; |
| 79 | case 7: |
| 80 | brw->blorp.mocs.tex = GEN7_MOCS_L3; |
| 81 | brw->blorp.mocs.rb = GEN7_MOCS_L3; |
| 82 | brw->blorp.mocs.vb = GEN7_MOCS_L3; |
Jason Ekstrand | bc159ff | 2016-08-18 10:02:03 -0700 | [diff] [blame] | 83 | if (brw->is_haswell) { |
| 84 | brw->blorp.exec = gen75_blorp_exec; |
| 85 | } else { |
| 86 | brw->blorp.exec = gen7_blorp_exec; |
| 87 | } |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 88 | break; |
| 89 | case 8: |
| 90 | brw->blorp.mocs.tex = BDW_MOCS_WB; |
| 91 | brw->blorp.mocs.rb = BDW_MOCS_PTE; |
| 92 | brw->blorp.mocs.vb = BDW_MOCS_WB; |
Jason Ekstrand | bc159ff | 2016-08-18 10:02:03 -0700 | [diff] [blame] | 93 | brw->blorp.exec = gen8_blorp_exec; |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 94 | break; |
| 95 | case 9: |
| 96 | brw->blorp.mocs.tex = SKL_MOCS_WB; |
| 97 | brw->blorp.mocs.rb = SKL_MOCS_PTE; |
| 98 | brw->blorp.mocs.vb = SKL_MOCS_WB; |
Jason Ekstrand | bc159ff | 2016-08-18 10:02:03 -0700 | [diff] [blame] | 99 | brw->blorp.exec = gen9_blorp_exec; |
Jason Ekstrand | 6d2f8f8 | 2016-08-17 09:31:27 -0700 | [diff] [blame] | 100 | break; |
| 101 | default: |
| 102 | unreachable("Invalid gen"); |
| 103 | } |
| 104 | |
Jason Ekstrand | 600446c | 2016-08-26 10:07:40 -0700 | [diff] [blame] | 105 | brw->blorp.lookup_shader = brw_blorp_lookup_shader; |
| 106 | brw->blorp.upload_shader = brw_blorp_upload_shader; |
Jason Ekstrand | a14d1b6 | 2016-08-15 15:07:22 -0700 | [diff] [blame] | 107 | } |
| 108 | |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 109 | static void |
| 110 | apply_gen6_stencil_hiz_offset(struct isl_surf *surf, |
| 111 | struct intel_mipmap_tree *mt, |
| 112 | uint32_t lod, |
| 113 | uint32_t *offset) |
| 114 | { |
| 115 | assert(mt->array_layout == ALL_SLICES_AT_EACH_LOD); |
| 116 | |
Jason Ekstrand | d8644f3 | 2016-07-19 19:59:16 -0700 | [diff] [blame] | 117 | if (mt->format == MESA_FORMAT_S_UINT8) { |
| 118 | /* Note: we can't compute the stencil offset using |
| 119 | * intel_miptree_get_aligned_offset(), because the miptree |
| 120 | * claims that the region is untiled even though it's W tiled. |
| 121 | */ |
| 122 | *offset = mt->level[lod].level_y * mt->pitch + |
| 123 | mt->level[lod].level_x * 64; |
| 124 | } else { |
| 125 | *offset = intel_miptree_get_aligned_offset(mt, |
| 126 | mt->level[lod].level_x, |
Jason Ekstrand | c30b716 | 2016-10-24 10:38:07 -0700 | [diff] [blame] | 127 | mt->level[lod].level_y); |
Jason Ekstrand | d8644f3 | 2016-07-19 19:59:16 -0700 | [diff] [blame] | 128 | } |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 129 | |
| 130 | surf->logical_level0_px.width = minify(surf->logical_level0_px.width, lod); |
| 131 | surf->logical_level0_px.height = minify(surf->logical_level0_px.height, lod); |
| 132 | surf->phys_level0_sa.width = minify(surf->phys_level0_sa.width, lod); |
| 133 | surf->phys_level0_sa.height = minify(surf->phys_level0_sa.height, lod); |
| 134 | surf->levels = 1; |
| 135 | surf->array_pitch_el_rows = |
| 136 | ALIGN(surf->phys_level0_sa.height, surf->image_alignment_el.height); |
| 137 | } |
| 138 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 139 | static void |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 140 | blorp_surf_for_miptree(struct brw_context *brw, |
| 141 | struct blorp_surf *surf, |
| 142 | struct intel_mipmap_tree *mt, |
| 143 | bool is_render_target, |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 144 | uint32_t safe_aux_usage, |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 145 | unsigned *level, |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 146 | unsigned start_layer, unsigned num_layers, |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 147 | struct isl_surf tmp_surfs[2]) |
Paul Berry | 2c5510b | 2012-04-29 22:00:46 -0700 | [diff] [blame] | 148 | { |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 149 | if (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS || |
| 150 | mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) { |
| 151 | const unsigned num_samples = MAX2(1, mt->num_samples); |
| 152 | for (unsigned i = 0; i < num_layers; i++) { |
| 153 | for (unsigned s = 0; s < num_samples; s++) { |
| 154 | const unsigned phys_layer = (start_layer + i) * num_samples + s; |
| 155 | intel_miptree_check_level_layer(mt, *level, phys_layer); |
| 156 | } |
| 157 | } |
| 158 | } else { |
| 159 | for (unsigned i = 0; i < num_layers; i++) |
| 160 | intel_miptree_check_level_layer(mt, *level, start_layer + i); |
| 161 | } |
| 162 | |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 163 | intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]); |
| 164 | surf->surf = &tmp_surfs[0]; |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 165 | surf->addr = (struct blorp_address) { |
| 166 | .buffer = mt->bo, |
| 167 | .offset = mt->offset, |
| 168 | .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER : |
| 169 | I915_GEM_DOMAIN_SAMPLER, |
| 170 | .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0, |
| 171 | }; |
Jason Ekstrand | b82de88 | 2016-06-22 15:33:44 -0700 | [diff] [blame] | 172 | |
Jason Ekstrand | d8644f3 | 2016-07-19 19:59:16 -0700 | [diff] [blame] | 173 | if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 && |
| 174 | mt->array_layout == ALL_SLICES_AT_EACH_LOD) { |
| 175 | /* Sandy bridge stencil and HiZ use this ALL_SLICES_AT_EACH_LOD hack in |
| 176 | * order to allow for layered rendering. The hack makes each LOD of the |
| 177 | * stencil or HiZ buffer a single tightly packed array surface at some |
| 178 | * offset into the surface. Since ISL doesn't know how to deal with the |
| 179 | * crazy ALL_SLICES_AT_EACH_LOD layout and since we have to do a manual |
| 180 | * offset of it anyway, we might as well do the offset here and keep the |
| 181 | * hacks inside the i965 driver. |
| 182 | * |
| 183 | * See also gen6_depth_stencil_state.c |
| 184 | */ |
| 185 | uint32_t offset; |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 186 | apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset); |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 187 | surf->addr.offset += offset; |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 188 | *level = 0; |
Jason Ekstrand | d8644f3 | 2016-07-19 19:59:16 -0700 | [diff] [blame] | 189 | } |
| 190 | |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 191 | struct isl_surf *aux_surf = &tmp_surfs[1]; |
| 192 | intel_miptree_get_aux_isl_surf(brw, mt, aux_surf, &surf->aux_usage); |
Jason Ekstrand | 4d86b3f | 2016-07-01 16:01:56 -0700 | [diff] [blame] | 193 | |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 194 | if (surf->aux_usage != ISL_AUX_USAGE_NONE) { |
| 195 | if (surf->aux_usage == ISL_AUX_USAGE_HIZ) { |
| 196 | /* If we're not going to use it as a depth buffer, resolve HiZ */ |
| 197 | if (!(safe_aux_usage & (1 << ISL_AUX_USAGE_HIZ))) { |
| 198 | for (unsigned i = 0; i < num_layers; i++) { |
| 199 | intel_miptree_slice_resolve_depth(brw, mt, *level, |
| 200 | start_layer + i); |
| 201 | |
| 202 | /* If we're rendering to it then we'll need a HiZ resolve once |
| 203 | * we're done before we can use it with HiZ again. |
| 204 | */ |
| 205 | if (is_render_target) |
| 206 | intel_miptree_slice_set_needs_hiz_resolve(mt, *level, |
| 207 | start_layer + i); |
| 208 | } |
| 209 | surf->aux_usage = ISL_AUX_USAGE_NONE; |
| 210 | } |
| 211 | } else if (!(safe_aux_usage & (1 << surf->aux_usage))) { |
| 212 | uint32_t flags = 0; |
| 213 | if (safe_aux_usage & (1 << ISL_AUX_USAGE_CCS_E)) |
| 214 | flags |= INTEL_MIPTREE_IGNORE_CCS_E; |
| 215 | |
Topi Pohjolainen | 9c7717c | 2016-09-15 09:05:55 +0300 | [diff] [blame] | 216 | intel_miptree_resolve_color(brw, mt, |
| 217 | *level, start_layer, num_layers, flags); |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 218 | |
Topi Pohjolainen | ea2c419 | 2016-06-09 10:59:06 +0300 | [diff] [blame] | 219 | assert(!intel_miptree_has_color_unresolved(mt, *level, 1, |
| 220 | start_layer, num_layers)); |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 221 | surf->aux_usage = ISL_AUX_USAGE_NONE; |
| 222 | } |
| 223 | } |
| 224 | |
Topi Pohjolainen | 71d48d6 | 2016-07-06 12:29:41 +0300 | [diff] [blame] | 225 | if (is_render_target) |
Topi Pohjolainen | 17e6a21 | 2016-09-15 08:22:34 +0300 | [diff] [blame] | 226 | intel_miptree_used_for_rendering(brw, mt, *level, |
| 227 | start_layer, num_layers); |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 228 | |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 229 | if (surf->aux_usage != ISL_AUX_USAGE_NONE) { |
Jason Ekstrand | 4d86b3f | 2016-07-01 16:01:56 -0700 | [diff] [blame] | 230 | /* We only really need a clear color if we also have an auxiliary |
| 231 | * surface. Without one, it does nothing. |
| 232 | */ |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 233 | surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt); |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 234 | |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 235 | surf->aux_surf = aux_surf; |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 236 | surf->aux_addr = (struct blorp_address) { |
| 237 | .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER : |
| 238 | I915_GEM_DOMAIN_SAMPLER, |
| 239 | .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0, |
| 240 | }; |
| 241 | |
Jordan Justen | 0041169 | 2016-10-21 12:56:49 +0100 | [diff] [blame] | 242 | if (mt->mcs_buf) { |
Ben Widawsky | 36d1c55 | 2016-10-21 14:20:39 +0100 | [diff] [blame] | 243 | surf->aux_addr.buffer = mt->mcs_buf->bo; |
| 244 | surf->aux_addr.offset = mt->mcs_buf->offset; |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 245 | } else { |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 246 | assert(surf->aux_usage == ISL_AUX_USAGE_HIZ); |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 247 | struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt; |
| 248 | if (hiz_mt) { |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 249 | surf->aux_addr.buffer = hiz_mt->bo; |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 250 | if (brw->gen == 6 && |
| 251 | hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) { |
| 252 | /* gen6 requires the HiZ buffer to be manually offset to the |
| 253 | * right location. We could fixup the surf but it doesn't |
| 254 | * matter since most of those fields don't matter. |
| 255 | */ |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 256 | apply_gen6_stencil_hiz_offset(aux_surf, hiz_mt, *level, |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 257 | &surf->aux_addr.offset); |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 258 | } else { |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 259 | surf->aux_addr.offset = 0; |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 260 | } |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 261 | assert(hiz_mt->pitch == aux_surf->row_pitch); |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 262 | } else { |
Ben Widawsky | c53e9c9 | 2016-10-21 15:10:56 +0100 | [diff] [blame] | 263 | surf->aux_addr.buffer = mt->hiz_buf->aux_base.bo; |
| 264 | surf->aux_addr.offset = mt->hiz_buf->aux_base.offset; |
Jason Ekstrand | 406c503 | 2016-07-22 14:41:43 -0700 | [diff] [blame] | 265 | } |
| 266 | } |
Jason Ekstrand | b82de88 | 2016-06-22 15:33:44 -0700 | [diff] [blame] | 267 | } else { |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 268 | surf->aux_addr = (struct blorp_address) { |
| 269 | .buffer = NULL, |
| 270 | }; |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 271 | memset(&surf->clear_color, 0, sizeof(surf->clear_color)); |
Jason Ekstrand | b82de88 | 2016-06-22 15:33:44 -0700 | [diff] [blame] | 272 | } |
Jason Ekstrand | ac08bc8 | 2016-08-18 02:19:29 -0700 | [diff] [blame] | 273 | assert((surf->aux_usage == ISL_AUX_USAGE_NONE) == |
| 274 | (surf->aux_addr.buffer == NULL)); |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 275 | } |
| 276 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 277 | static enum isl_format |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 278 | brw_blorp_to_isl_format(struct brw_context *brw, mesa_format format, |
| 279 | bool is_render_target) |
| 280 | { |
| 281 | switch (format) { |
| 282 | case MESA_FORMAT_NONE: |
| 283 | return ISL_FORMAT_UNSUPPORTED; |
| 284 | case MESA_FORMAT_S_UINT8: |
| 285 | return ISL_FORMAT_R8_UINT; |
| 286 | case MESA_FORMAT_Z24_UNORM_X8_UINT: |
| 287 | return ISL_FORMAT_R24_UNORM_X8_TYPELESS; |
| 288 | case MESA_FORMAT_Z_FLOAT32: |
| 289 | return ISL_FORMAT_R32_FLOAT; |
| 290 | case MESA_FORMAT_Z_UNORM16: |
| 291 | return ISL_FORMAT_R16_UNORM; |
| 292 | default: { |
| 293 | if (is_render_target) { |
| 294 | assert(brw->format_supported_as_render_target[format]); |
| 295 | return brw->render_target_format[format]; |
| 296 | } else { |
| 297 | return brw_format_for_mesa_format(format); |
| 298 | } |
| 299 | break; |
| 300 | } |
| 301 | } |
| 302 | } |
| 303 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 304 | /** |
Jason Ekstrand | 2dba548 | 2016-08-27 21:48:40 -0700 | [diff] [blame] | 305 | * Convert an swizzle enumeration (i.e. SWIZZLE_X) to one of the Gen7.5+ |
| 306 | * "Shader Channel Select" enumerations (i.e. HSW_SCS_RED). The mappings are |
| 307 | * |
| 308 | * SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_ZERO, SWIZZLE_ONE |
| 309 | * 0 1 2 3 4 5 |
| 310 | * 4 5 6 7 0 1 |
| 311 | * SCS_RED, SCS_GREEN, SCS_BLUE, SCS_ALPHA, SCS_ZERO, SCS_ONE |
| 312 | * |
| 313 | * which is simply adding 4 then modding by 8 (or anding with 7). |
| 314 | * |
| 315 | * We then may need to apply workarounds for textureGather hardware bugs. |
| 316 | */ |
| 317 | static enum isl_channel_select |
| 318 | swizzle_to_scs(GLenum swizzle) |
| 319 | { |
| 320 | return (enum isl_channel_select)((swizzle + 4) & 7); |
| 321 | } |
| 322 | |
Jason Ekstrand | 54db5af | 2016-09-03 11:40:09 -0700 | [diff] [blame] | 323 | static unsigned |
| 324 | physical_to_logical_layer(struct intel_mipmap_tree *mt, |
| 325 | unsigned physical_layer) |
| 326 | { |
| 327 | if (mt->num_samples > 1 && |
| 328 | (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS || |
| 329 | mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS)) { |
| 330 | assert(physical_layer % mt->num_samples == 0); |
| 331 | return physical_layer / mt->num_samples; |
| 332 | } else { |
| 333 | return physical_layer; |
| 334 | } |
| 335 | } |
| 336 | |
Jason Ekstrand | 2dba548 | 2016-08-27 21:48:40 -0700 | [diff] [blame] | 337 | /** |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 338 | * Note: if the src (or dst) is a 2D multisample array texture on Gen7+ using |
| 339 | * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src_layer (dst_layer) is |
| 340 | * the physical layer holding sample 0. So, for example, if |
| 341 | * src_mt->num_samples == 4, then logical layer n corresponds to src_layer == |
| 342 | * 4*n. |
| 343 | */ |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 344 | void |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 345 | brw_blorp_blit_miptrees(struct brw_context *brw, |
| 346 | struct intel_mipmap_tree *src_mt, |
| 347 | unsigned src_level, unsigned src_layer, |
| 348 | mesa_format src_format, int src_swizzle, |
| 349 | struct intel_mipmap_tree *dst_mt, |
| 350 | unsigned dst_level, unsigned dst_layer, |
| 351 | mesa_format dst_format, |
| 352 | float src_x0, float src_y0, |
| 353 | float src_x1, float src_y1, |
| 354 | float dst_x0, float dst_y0, |
| 355 | float dst_x1, float dst_y1, |
| 356 | GLenum filter, bool mirror_x, bool mirror_y, |
| 357 | bool decode_srgb, bool encode_srgb) |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 358 | { |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 359 | /* Blorp operates in logical layers */ |
| 360 | src_layer = physical_to_logical_layer(src_mt, src_layer); |
| 361 | dst_layer = physical_to_logical_layer(dst_mt, dst_layer); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 362 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 363 | DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)" |
| 364 | "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n", |
| 365 | __func__, |
| 366 | src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt, |
| 367 | src_level, src_layer, src_x0, src_y0, src_x1, src_y1, |
| 368 | dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt, |
| 369 | dst_level, dst_layer, dst_x0, dst_y0, dst_x1, dst_y1, |
| 370 | mirror_x, mirror_y); |
| 371 | |
| 372 | if (!decode_srgb && _mesa_get_format_color_encoding(src_format) == GL_SRGB) |
| 373 | src_format = _mesa_get_srgb_format_linear(src_format); |
| 374 | |
| 375 | if (!encode_srgb && _mesa_get_format_color_encoding(dst_format) == GL_SRGB) |
| 376 | dst_format = _mesa_get_srgb_format_linear(dst_format); |
| 377 | |
| 378 | /* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F |
| 379 | * texture, the above code configures the source format for L32_FLOAT or |
| 380 | * I32_FLOAT, and the destination format for R32_FLOAT. On Sandy Bridge, |
| 381 | * the SAMPLE message appears to handle multisampled L32_FLOAT and |
| 382 | * I32_FLOAT textures incorrectly, resulting in blocky artifacts. So work |
| 383 | * around the problem by using a source format of R32_FLOAT. This |
| 384 | * shouldn't affect rendering correctness, since the destination format is |
| 385 | * R32_FLOAT, so only the contents of the red channel matters. |
| 386 | */ |
| 387 | if (brw->gen == 6 && |
| 388 | src_mt->num_samples > 1 && dst_mt->num_samples <= 1 && |
| 389 | src_mt->format == dst_mt->format && |
| 390 | (dst_format == MESA_FORMAT_L_FLOAT32 || |
| 391 | dst_format == MESA_FORMAT_I_FLOAT32)) { |
| 392 | src_format = dst_format = MESA_FORMAT_R_FLOAT32; |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 393 | } |
| 394 | |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 395 | uint32_t src_usage_flags = (1 << ISL_AUX_USAGE_MCS); |
| 396 | if (src_format == src_mt->format) |
| 397 | src_usage_flags |= (1 << ISL_AUX_USAGE_CCS_E); |
| 398 | |
| 399 | uint32_t dst_usage_flags = (1 << ISL_AUX_USAGE_MCS); |
| 400 | if (dst_format == dst_mt->format) { |
| 401 | dst_usage_flags |= (1 << ISL_AUX_USAGE_CCS_E) | |
| 402 | (1 << ISL_AUX_USAGE_CCS_D); |
| 403 | } |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 404 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 405 | struct isl_surf tmp_surfs[4]; |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 406 | struct blorp_surf src_surf, dst_surf; |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 407 | blorp_surf_for_miptree(brw, &src_surf, src_mt, false, src_usage_flags, |
| 408 | &src_level, src_layer, 1, &tmp_surfs[0]); |
| 409 | blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true, dst_usage_flags, |
| 410 | &dst_level, dst_layer, 1, &tmp_surfs[2]); |
Jason Ekstrand | 75deae9 | 2016-07-19 19:04:03 -0700 | [diff] [blame] | 411 | |
Jason Ekstrand | 2dba548 | 2016-08-27 21:48:40 -0700 | [diff] [blame] | 412 | struct isl_swizzle src_isl_swizzle = { |
| 413 | .r = swizzle_to_scs(GET_SWZ(src_swizzle, 0)), |
| 414 | .g = swizzle_to_scs(GET_SWZ(src_swizzle, 1)), |
| 415 | .b = swizzle_to_scs(GET_SWZ(src_swizzle, 2)), |
| 416 | .a = swizzle_to_scs(GET_SWZ(src_swizzle, 3)), |
| 417 | }; |
| 418 | |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 419 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 420 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 421 | blorp_blit(&batch, &src_surf, src_level, src_layer, |
Jason Ekstrand | 2dba548 | 2016-08-27 21:48:40 -0700 | [diff] [blame] | 422 | brw_blorp_to_isl_format(brw, src_format, false), src_isl_swizzle, |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 423 | &dst_surf, dst_level, dst_layer, |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 424 | brw_blorp_to_isl_format(brw, dst_format, true), |
Jason Ekstrand | 2fc9c7e | 2016-08-27 21:57:51 -0700 | [diff] [blame] | 425 | ISL_SWIZZLE_IDENTITY, |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 426 | src_x0, src_y0, src_x1, src_y1, |
| 427 | dst_x0, dst_y0, dst_x1, dst_y1, |
| 428 | filter, mirror_x, mirror_y); |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 429 | blorp_batch_finish(&batch); |
Paul Berry | 506d70b | 2012-04-29 22:44:25 -0700 | [diff] [blame] | 430 | } |
| 431 | |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 432 | void |
| 433 | brw_blorp_copy_miptrees(struct brw_context *brw, |
| 434 | struct intel_mipmap_tree *src_mt, |
| 435 | unsigned src_level, unsigned src_layer, |
| 436 | struct intel_mipmap_tree *dst_mt, |
| 437 | unsigned dst_level, unsigned dst_layer, |
| 438 | unsigned src_x, unsigned src_y, |
| 439 | unsigned dst_x, unsigned dst_y, |
| 440 | unsigned src_width, unsigned src_height) |
| 441 | { |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 442 | DBG("%s from %dx %s mt %p %d %d (%d,%d) %dx%d" |
| 443 | "to %dx %s mt %p %d %d (%d,%d)\n", |
| 444 | __func__, |
| 445 | src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt, |
| 446 | src_level, src_layer, src_x, src_y, src_width, src_height, |
| 447 | dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt, |
| 448 | dst_level, dst_layer, dst_x, dst_y); |
| 449 | |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 450 | struct isl_surf tmp_surfs[4]; |
| 451 | struct blorp_surf src_surf, dst_surf; |
| 452 | blorp_surf_for_miptree(brw, &src_surf, src_mt, false, |
Jason Ekstrand | 2b5644e | 2016-10-26 02:27:01 -0700 | [diff] [blame] | 453 | (1 << ISL_AUX_USAGE_MCS) | |
| 454 | (1 << ISL_AUX_USAGE_CCS_E), |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 455 | &src_level, src_layer, 1, &tmp_surfs[0]); |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 456 | blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true, |
Jason Ekstrand | 2b5644e | 2016-10-26 02:27:01 -0700 | [diff] [blame] | 457 | (1 << ISL_AUX_USAGE_MCS) | |
| 458 | (1 << ISL_AUX_USAGE_CCS_E), |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 459 | &dst_level, dst_layer, 1, &tmp_surfs[2]); |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 460 | |
| 461 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 462 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 463 | blorp_copy(&batch, &src_surf, src_level, src_layer, |
| 464 | &dst_surf, dst_level, dst_layer, |
| 465 | src_x, src_y, dst_x, dst_y, src_width, src_height); |
| 466 | blorp_batch_finish(&batch); |
Jason Ekstrand | 540395b | 2016-09-08 21:27:01 -0700 | [diff] [blame] | 467 | } |
| 468 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 469 | static struct intel_mipmap_tree * |
| 470 | find_miptree(GLbitfield buffer_bit, struct intel_renderbuffer *irb) |
Paul Berry | 2c5510b | 2012-04-29 22:00:46 -0700 | [diff] [blame] | 471 | { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 472 | struct intel_mipmap_tree *mt = irb->mt; |
| 473 | if (buffer_bit == GL_STENCIL_BUFFER_BIT && mt->stencil_mt) |
| 474 | mt = mt->stencil_mt; |
| 475 | return mt; |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 476 | } |
| 477 | |
| 478 | static int |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 479 | blorp_get_texture_swizzle(const struct intel_renderbuffer *irb) |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 480 | { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 481 | return irb->Base.Base._BaseFormat == GL_RGB ? |
| 482 | MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE) : |
| 483 | SWIZZLE_XYZW; |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 484 | } |
| 485 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 486 | static void |
| 487 | do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit, |
| 488 | struct intel_renderbuffer *src_irb, mesa_format src_format, |
| 489 | struct intel_renderbuffer *dst_irb, mesa_format dst_format, |
| 490 | GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1, |
| 491 | GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1, |
| 492 | GLenum filter, bool mirror_x, bool mirror_y) |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 493 | { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 494 | const struct gl_context *ctx = &brw->ctx; |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 495 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 496 | /* Find source/dst miptrees */ |
| 497 | struct intel_mipmap_tree *src_mt = find_miptree(buffer_bit, src_irb); |
| 498 | struct intel_mipmap_tree *dst_mt = find_miptree(buffer_bit, dst_irb); |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 499 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 500 | const bool do_srgb = ctx->Color.sRGBEnabled; |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 501 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 502 | /* Do the blit */ |
| 503 | brw_blorp_blit_miptrees(brw, |
| 504 | src_mt, src_irb->mt_level, src_irb->mt_layer, |
| 505 | src_format, blorp_get_texture_swizzle(src_irb), |
| 506 | dst_mt, dst_irb->mt_level, dst_irb->mt_layer, |
| 507 | dst_format, |
| 508 | srcX0, srcY0, srcX1, srcY1, |
| 509 | dstX0, dstY0, dstX1, dstY1, |
| 510 | filter, mirror_x, mirror_y, |
| 511 | do_srgb, do_srgb); |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 512 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 513 | dst_irb->need_downsample = true; |
Jason Ekstrand | c1fe885 | 2016-04-27 17:16:30 -0700 | [diff] [blame] | 514 | } |
| 515 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 516 | static bool |
| 517 | try_blorp_blit(struct brw_context *brw, |
| 518 | const struct gl_framebuffer *read_fb, |
| 519 | const struct gl_framebuffer *draw_fb, |
| 520 | GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1, |
| 521 | GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1, |
| 522 | GLenum filter, GLbitfield buffer_bit) |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 523 | { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 524 | struct gl_context *ctx = &brw->ctx; |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 525 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 526 | /* Sync up the state of window system buffers. We need to do this before |
| 527 | * we go looking for the buffers. |
| 528 | */ |
| 529 | intel_prepare_render(brw); |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 530 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 531 | bool mirror_x, mirror_y; |
| 532 | if (brw_meta_mirror_clip_and_scissor(ctx, read_fb, draw_fb, |
| 533 | &srcX0, &srcY0, &srcX1, &srcY1, |
| 534 | &dstX0, &dstY0, &dstX1, &dstY1, |
| 535 | &mirror_x, &mirror_y)) |
| 536 | return true; |
Jason Ekstrand | 871893c | 2016-06-27 17:30:35 -0700 | [diff] [blame] | 537 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 538 | /* Find buffers */ |
| 539 | struct intel_renderbuffer *src_irb; |
| 540 | struct intel_renderbuffer *dst_irb; |
| 541 | struct intel_mipmap_tree *src_mt; |
| 542 | struct intel_mipmap_tree *dst_mt; |
| 543 | switch (buffer_bit) { |
| 544 | case GL_COLOR_BUFFER_BIT: |
| 545 | src_irb = intel_renderbuffer(read_fb->_ColorReadBuffer); |
| 546 | for (unsigned i = 0; i < draw_fb->_NumColorDrawBuffers; ++i) { |
| 547 | dst_irb = intel_renderbuffer(draw_fb->_ColorDrawBuffers[i]); |
| 548 | if (dst_irb) |
| 549 | do_blorp_blit(brw, buffer_bit, |
| 550 | src_irb, src_irb->Base.Base.Format, |
| 551 | dst_irb, dst_irb->Base.Base.Format, |
| 552 | srcX0, srcY0, srcX1, srcY1, |
| 553 | dstX0, dstY0, dstX1, dstY1, |
| 554 | filter, mirror_x, mirror_y); |
| 555 | } |
| 556 | break; |
| 557 | case GL_DEPTH_BUFFER_BIT: |
| 558 | src_irb = |
| 559 | intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer); |
| 560 | dst_irb = |
| 561 | intel_renderbuffer(draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer); |
| 562 | src_mt = find_miptree(buffer_bit, src_irb); |
| 563 | dst_mt = find_miptree(buffer_bit, dst_irb); |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 564 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 565 | /* We can't handle format conversions between Z24 and other formats |
| 566 | * since we have to lie about the surface format. See the comments in |
| 567 | * brw_blorp_surface_info::set(). |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 568 | */ |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 569 | if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) != |
| 570 | (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT)) |
| 571 | return false; |
| 572 | |
| 573 | do_blorp_blit(brw, buffer_bit, src_irb, MESA_FORMAT_NONE, |
| 574 | dst_irb, MESA_FORMAT_NONE, srcX0, srcY0, |
| 575 | srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, |
| 576 | filter, mirror_x, mirror_y); |
| 577 | break; |
| 578 | case GL_STENCIL_BUFFER_BIT: |
| 579 | src_irb = |
| 580 | intel_renderbuffer(read_fb->Attachment[BUFFER_STENCIL].Renderbuffer); |
| 581 | dst_irb = |
| 582 | intel_renderbuffer(draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer); |
| 583 | do_blorp_blit(brw, buffer_bit, src_irb, MESA_FORMAT_NONE, |
| 584 | dst_irb, MESA_FORMAT_NONE, srcX0, srcY0, |
| 585 | srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, |
| 586 | filter, mirror_x, mirror_y); |
| 587 | break; |
| 588 | default: |
| 589 | unreachable("not reached"); |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 590 | } |
| 591 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 592 | return true; |
| 593 | } |
| 594 | |
| 595 | bool |
| 596 | brw_blorp_copytexsubimage(struct brw_context *brw, |
| 597 | struct gl_renderbuffer *src_rb, |
| 598 | struct gl_texture_image *dst_image, |
| 599 | int slice, |
| 600 | int srcX0, int srcY0, |
| 601 | int dstX0, int dstY0, |
| 602 | int width, int height) |
| 603 | { |
| 604 | struct gl_context *ctx = &brw->ctx; |
| 605 | struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); |
| 606 | struct intel_texture_image *intel_image = intel_texture_image(dst_image); |
| 607 | |
| 608 | /* No pixel transfer operations (zoom, bias, mapping), just a blit */ |
| 609 | if (brw->ctx._ImageTransferState) |
| 610 | return false; |
| 611 | |
| 612 | /* Sync up the state of window system buffers. We need to do this before |
| 613 | * we go looking at the src renderbuffer's miptree. |
| 614 | */ |
| 615 | intel_prepare_render(brw); |
| 616 | |
| 617 | struct intel_mipmap_tree *src_mt = src_irb->mt; |
| 618 | struct intel_mipmap_tree *dst_mt = intel_image->mt; |
| 619 | |
| 620 | /* There is support for only up to eight samples. */ |
| 621 | if (src_mt->num_samples > 8 || dst_mt->num_samples > 8) |
| 622 | return false; |
| 623 | |
| 624 | /* BLORP is only supported from Gen6 onwards. */ |
| 625 | if (brw->gen < 6) |
| 626 | return false; |
| 627 | |
| 628 | if (_mesa_get_format_base_format(src_rb->Format) != |
| 629 | _mesa_get_format_base_format(dst_image->TexFormat)) { |
| 630 | return false; |
| 631 | } |
| 632 | |
| 633 | /* We can't handle format conversions between Z24 and other formats since |
| 634 | * we have to lie about the surface format. See the comments in |
| 635 | * brw_blorp_surface_info::set(). |
| 636 | */ |
| 637 | if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) != |
| 638 | (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT)) { |
| 639 | return false; |
| 640 | } |
| 641 | |
| 642 | if (!brw->format_supported_as_render_target[dst_image->TexFormat]) |
| 643 | return false; |
| 644 | |
| 645 | /* Source clipping shouldn't be necessary, since copytexsubimage (in |
| 646 | * src/mesa/main/teximage.c) calls _mesa_clip_copytexsubimage() which |
| 647 | * takes care of it. |
| 648 | * |
| 649 | * Destination clipping shouldn't be necessary since the restrictions on |
| 650 | * glCopyTexSubImage prevent the user from specifying a destination rectangle |
| 651 | * that falls outside the bounds of the destination texture. |
| 652 | * See error_check_subtexture_dimensions(). |
| 653 | */ |
| 654 | |
| 655 | int srcY1 = srcY0 + height; |
| 656 | int srcX1 = srcX0 + width; |
| 657 | int dstX1 = dstX0 + width; |
| 658 | int dstY1 = dstY0 + height; |
| 659 | |
| 660 | /* Account for the fact that in the system framebuffer, the origin is at |
| 661 | * the lower left. |
| 662 | */ |
| 663 | bool mirror_y = false; |
| 664 | if (_mesa_is_winsys_fbo(ctx->ReadBuffer)) { |
| 665 | GLint tmp = src_rb->Height - srcY0; |
| 666 | srcY0 = src_rb->Height - srcY1; |
| 667 | srcY1 = tmp; |
| 668 | mirror_y = true; |
| 669 | } |
| 670 | |
| 671 | /* Account for face selection and texture view MinLayer */ |
| 672 | int dst_slice = slice + dst_image->TexObject->MinLayer + dst_image->Face; |
| 673 | int dst_level = dst_image->Level + dst_image->TexObject->MinLevel; |
| 674 | |
| 675 | brw_blorp_blit_miptrees(brw, |
| 676 | src_mt, src_irb->mt_level, src_irb->mt_layer, |
| 677 | src_rb->Format, blorp_get_texture_swizzle(src_irb), |
| 678 | dst_mt, dst_level, dst_slice, |
| 679 | dst_image->TexFormat, |
| 680 | srcX0, srcY0, srcX1, srcY1, |
| 681 | dstX0, dstY0, dstX1, dstY1, |
| 682 | GL_NEAREST, false, mirror_y, |
| 683 | false, false); |
| 684 | |
| 685 | /* If we're copying to a packed depth stencil texture and the source |
| 686 | * framebuffer has separate stencil, we need to also copy the stencil data |
| 687 | * over. |
| 688 | */ |
| 689 | src_rb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; |
| 690 | if (_mesa_get_format_bits(dst_image->TexFormat, GL_STENCIL_BITS) > 0 && |
| 691 | src_rb != NULL) { |
| 692 | src_irb = intel_renderbuffer(src_rb); |
| 693 | src_mt = src_irb->mt; |
| 694 | |
| 695 | if (src_mt->stencil_mt) |
| 696 | src_mt = src_mt->stencil_mt; |
| 697 | if (dst_mt->stencil_mt) |
| 698 | dst_mt = dst_mt->stencil_mt; |
| 699 | |
| 700 | if (src_mt != dst_mt) { |
| 701 | brw_blorp_blit_miptrees(brw, |
| 702 | src_mt, src_irb->mt_level, src_irb->mt_layer, |
| 703 | src_mt->format, |
| 704 | blorp_get_texture_swizzle(src_irb), |
| 705 | dst_mt, dst_level, dst_slice, |
| 706 | dst_mt->format, |
| 707 | srcX0, srcY0, srcX1, srcY1, |
| 708 | dstX0, dstY0, dstX1, dstY1, |
| 709 | GL_NEAREST, false, mirror_y, |
| 710 | false, false); |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | return true; |
| 715 | } |
| 716 | |
| 717 | |
| 718 | GLbitfield |
| 719 | brw_blorp_framebuffer(struct brw_context *brw, |
| 720 | struct gl_framebuffer *readFb, |
| 721 | struct gl_framebuffer *drawFb, |
| 722 | GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, |
| 723 | GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, |
| 724 | GLbitfield mask, GLenum filter) |
| 725 | { |
| 726 | /* BLORP is not supported before Gen6. */ |
| 727 | if (brw->gen < 6) |
| 728 | return mask; |
| 729 | |
| 730 | static GLbitfield buffer_bits[] = { |
| 731 | GL_COLOR_BUFFER_BIT, |
| 732 | GL_DEPTH_BUFFER_BIT, |
| 733 | GL_STENCIL_BUFFER_BIT, |
| 734 | }; |
| 735 | |
| 736 | for (unsigned int i = 0; i < ARRAY_SIZE(buffer_bits); ++i) { |
| 737 | if ((mask & buffer_bits[i]) && |
| 738 | try_blorp_blit(brw, readFb, drawFb, |
| 739 | srcX0, srcY0, srcX1, srcY1, |
| 740 | dstX0, dstY0, dstX1, dstY1, |
| 741 | filter, buffer_bits[i])) { |
| 742 | mask &= ~buffer_bits[i]; |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | return mask; |
| 747 | } |
| 748 | |
| 749 | static bool |
| 750 | set_write_disables(const struct intel_renderbuffer *irb, |
| 751 | const GLubyte *color_mask, bool *color_write_disable) |
| 752 | { |
| 753 | /* Format information in the renderbuffer represents the requirements |
| 754 | * given by the client. There are cases where the backing miptree uses, |
| 755 | * for example, RGBA to represent RGBX. Since the client is only expecting |
| 756 | * RGB we can treat alpha as not used and write whatever we like into it. |
| 757 | */ |
| 758 | const GLenum base_format = irb->Base.Base._BaseFormat; |
| 759 | const int components = _mesa_base_format_component_count(base_format); |
| 760 | bool disables = false; |
| 761 | |
| 762 | assert(components > 0); |
| 763 | |
| 764 | for (int i = 0; i < components; i++) { |
| 765 | color_write_disable[i] = !color_mask[i]; |
| 766 | disables = disables || !color_mask[i]; |
| 767 | } |
| 768 | |
| 769 | return disables; |
| 770 | } |
| 771 | |
Jason Ekstrand | 54db5af | 2016-09-03 11:40:09 -0700 | [diff] [blame] | 772 | static unsigned |
| 773 | irb_logical_mt_layer(struct intel_renderbuffer *irb) |
| 774 | { |
| 775 | return physical_to_logical_layer(irb->mt, irb->mt_layer); |
| 776 | } |
| 777 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 778 | static bool |
| 779 | do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb, |
| 780 | struct gl_renderbuffer *rb, unsigned buf, |
Topi Pohjolainen | 1df4b66 | 2016-08-29 08:57:31 +0300 | [diff] [blame] | 781 | bool partial_clear, bool encode_srgb) |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 782 | { |
| 783 | struct gl_context *ctx = &brw->ctx; |
| 784 | struct intel_renderbuffer *irb = intel_renderbuffer(rb); |
| 785 | mesa_format format = irb->mt->format; |
| 786 | uint32_t x0, x1, y0, y1; |
| 787 | |
| 788 | if (!encode_srgb && _mesa_get_format_color_encoding(format) == GL_SRGB) |
| 789 | format = _mesa_get_srgb_format_linear(format); |
| 790 | |
| 791 | x0 = fb->_Xmin; |
| 792 | x1 = fb->_Xmax; |
| 793 | if (rb->Name != 0) { |
| 794 | y0 = fb->_Ymin; |
| 795 | y1 = fb->_Ymax; |
| 796 | } else { |
| 797 | y0 = rb->Height - fb->_Ymax; |
| 798 | y1 = rb->Height - fb->_Ymin; |
| 799 | } |
| 800 | |
Jason Ekstrand | e0bc2cb | 2016-08-08 12:10:26 -0700 | [diff] [blame] | 801 | /* If the clear region is empty, just return. */ |
| 802 | if (x0 == x1 || y0 == y1) |
| 803 | return true; |
| 804 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 805 | bool can_fast_clear = !partial_clear; |
| 806 | |
| 807 | bool color_write_disable[4] = { false, false, false, false }; |
| 808 | if (set_write_disables(irb, ctx->Color.ColorMask[buf], color_write_disable)) |
| 809 | can_fast_clear = false; |
| 810 | |
Ben Widawsky | fc78ee5 | 2016-12-20 14:29:05 +0000 | [diff] [blame] | 811 | if (irb->mt->aux_disable & INTEL_AUX_DISABLE_CCS || |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 812 | !brw_is_color_fast_clear_compatible(brw, irb->mt, &ctx->Color.ClearColor)) |
| 813 | can_fast_clear = false; |
| 814 | |
Topi Pohjolainen | ea2c419 | 2016-06-09 10:59:06 +0300 | [diff] [blame] | 815 | const unsigned logical_layer = irb_logical_mt_layer(irb); |
Topi Pohjolainen | ea2c419 | 2016-06-09 10:59:06 +0300 | [diff] [blame] | 816 | const enum intel_fast_clear_state fast_clear_state = |
| 817 | intel_miptree_get_fast_clear_state(irb->mt, irb->mt_level, |
| 818 | logical_layer); |
Topi Pohjolainen | 39712b2 | 2016-08-26 09:26:15 +0300 | [diff] [blame] | 819 | |
Topi Pohjolainen | dea8e7f | 2016-06-14 09:10:16 +0300 | [diff] [blame] | 820 | /* Surface state can only record one fast clear color value. Therefore |
| 821 | * unless different levels/layers agree on the color it can be used to |
| 822 | * represent only single level/layer. Here it will be reserved for the |
| 823 | * first slice (level 0, layer 0). |
| 824 | */ |
| 825 | if (irb->layer_count > 1 || irb->mt_level || irb->mt_layer) |
| 826 | can_fast_clear = false; |
| 827 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 828 | if (can_fast_clear) { |
Topi Pohjolainen | 7c75fd9 | 2016-06-12 20:49:54 +0300 | [diff] [blame] | 829 | union gl_color_union override_color = |
| 830 | brw_meta_convert_fast_clear_color(brw, irb->mt, |
| 831 | &ctx->Color.ClearColor); |
| 832 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 833 | /* Record the clear color in the miptree so that it will be |
| 834 | * programmed in SURFACE_STATE by later rendering and resolve |
| 835 | * operations. |
| 836 | */ |
| 837 | const bool color_updated = brw_meta_set_fast_clear_color( |
Topi Pohjolainen | 7c75fd9 | 2016-06-12 20:49:54 +0300 | [diff] [blame] | 838 | brw, &irb->mt->gen9_fast_clear_color, |
| 839 | &override_color); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 840 | |
| 841 | /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear |
| 842 | * is redundant and can be skipped. |
| 843 | */ |
Topi Pohjolainen | ea2c419 | 2016-06-09 10:59:06 +0300 | [diff] [blame] | 844 | if (!color_updated && fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR) |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 845 | return true; |
| 846 | |
| 847 | /* If the MCS buffer hasn't been allocated yet, we need to allocate |
| 848 | * it now. |
| 849 | */ |
Jordan Justen | 0041169 | 2016-10-21 12:56:49 +0100 | [diff] [blame] | 850 | if (!irb->mt->mcs_buf) { |
Grazvydas Ignotas | 6092169 | 2016-12-11 21:57:44 +0200 | [diff] [blame] | 851 | assert(!intel_miptree_is_lossless_compressed(brw, irb->mt)); |
Topi Pohjolainen | 39712b2 | 2016-08-26 09:26:15 +0300 | [diff] [blame] | 852 | if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt, false)) { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 853 | /* MCS allocation failed--probably this will only happen in |
| 854 | * out-of-memory conditions. But in any case, try to recover |
| 855 | * by falling back to a non-blorp clear technique. |
| 856 | */ |
| 857 | return false; |
| 858 | } |
| 859 | } |
| 860 | } |
| 861 | |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 862 | const unsigned num_layers = fb->MaxNumLayers ? irb->layer_count : 1; |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 863 | |
| 864 | /* We can't setup the blorp_surf until we've allocated the MCS above */ |
| 865 | struct isl_surf isl_tmp[2]; |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 866 | struct blorp_surf surf; |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 867 | unsigned level = irb->mt_level; |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 868 | blorp_surf_for_miptree(brw, &surf, irb->mt, true, |
| 869 | (1 << ISL_AUX_USAGE_MCS) | |
| 870 | (1 << ISL_AUX_USAGE_CCS_E) | |
| 871 | (1 << ISL_AUX_USAGE_CCS_D), |
| 872 | &level, logical_layer, num_layers, isl_tmp); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 873 | |
| 874 | if (can_fast_clear) { |
Topi Pohjolainen | 1df4b66 | 2016-08-29 08:57:31 +0300 | [diff] [blame] | 875 | DBG("%s (fast) to mt %p level %d layers %d+%d\n", __FUNCTION__, |
| 876 | irb->mt, irb->mt_level, irb->mt_layer, num_layers); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 877 | |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 878 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 879 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Topi Pohjolainen | a1c7de0 | 2016-08-26 18:44:18 +0300 | [diff] [blame] | 880 | blorp_fast_clear(&batch, &surf, |
Jason Ekstrand | 8721441 | 2016-08-23 17:13:07 -0700 | [diff] [blame] | 881 | (enum isl_format)brw->render_target_format[format], |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 882 | level, logical_layer, num_layers, |
Jason Ekstrand | 54db5af | 2016-09-03 11:40:09 -0700 | [diff] [blame] | 883 | x0, y0, x1, y1); |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 884 | blorp_batch_finish(&batch); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 885 | |
| 886 | /* Now that the fast clear has occurred, put the buffer in |
| 887 | * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing |
| 888 | * redundant clears. |
| 889 | */ |
Topi Pohjolainen | 17d7c5a | 2016-06-10 09:12:23 +0300 | [diff] [blame] | 890 | intel_miptree_set_fast_clear_state(brw, irb->mt, irb->mt_level, |
Topi Pohjolainen | ea2c419 | 2016-06-09 10:59:06 +0300 | [diff] [blame] | 891 | logical_layer, num_layers, |
| 892 | INTEL_FAST_CLEAR_STATE_CLEAR); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 893 | } else { |
Topi Pohjolainen | 1df4b66 | 2016-08-29 08:57:31 +0300 | [diff] [blame] | 894 | DBG("%s (slow) to mt %p level %d layer %d+%d\n", __FUNCTION__, |
| 895 | irb->mt, irb->mt_level, irb->mt_layer, num_layers); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 896 | |
| 897 | union isl_color_value clear_color; |
| 898 | memcpy(clear_color.f32, ctx->Color.ClearColor.f, sizeof(float) * 4); |
| 899 | |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 900 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 901 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Jason Ekstrand | c70be1e | 2016-08-30 18:01:27 -0700 | [diff] [blame] | 902 | blorp_clear(&batch, &surf, |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 903 | (enum isl_format)brw->render_target_format[format], |
Jason Ekstrand | c70be1e | 2016-08-30 18:01:27 -0700 | [diff] [blame] | 904 | ISL_SWIZZLE_IDENTITY, |
Jason Ekstrand | 54db5af | 2016-09-03 11:40:09 -0700 | [diff] [blame] | 905 | level, irb_logical_mt_layer(irb), num_layers, |
Jason Ekstrand | c70be1e | 2016-08-30 18:01:27 -0700 | [diff] [blame] | 906 | x0, y0, x1, y1, |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 907 | clear_color, color_write_disable); |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 908 | blorp_batch_finish(&batch); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 909 | } |
| 910 | |
Topi Pohjolainen | 9577977 | 2017-01-17 12:00:37 +0200 | [diff] [blame^] | 911 | /* |
| 912 | * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)": |
| 913 | * |
| 914 | * Any transition from any value in {Clear, Render, Resolve} to a |
| 915 | * different value in {Clear, Render, Resolve} requires end of pipe |
| 916 | * synchronization. |
| 917 | */ |
| 918 | brw_emit_pipe_control_flush(brw, |
| 919 | PIPE_CONTROL_RENDER_TARGET_FLUSH | |
| 920 | PIPE_CONTROL_CS_STALL); |
| 921 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 922 | return true; |
| 923 | } |
| 924 | |
| 925 | bool |
| 926 | brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb, |
| 927 | GLbitfield mask, bool partial_clear, bool encode_srgb) |
| 928 | { |
| 929 | for (unsigned buf = 0; buf < fb->_NumColorDrawBuffers; buf++) { |
| 930 | struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; |
| 931 | struct intel_renderbuffer *irb = intel_renderbuffer(rb); |
| 932 | |
| 933 | /* Only clear the buffers present in the provided mask */ |
| 934 | if (((1 << fb->_ColorDrawBufferIndexes[buf]) & mask) == 0) |
| 935 | continue; |
| 936 | |
| 937 | /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported, |
| 938 | * the framebuffer can be complete with some attachments missing. In |
| 939 | * this case the _ColorDrawBuffers pointer will be NULL. |
| 940 | */ |
| 941 | if (rb == NULL) |
| 942 | continue; |
| 943 | |
Topi Pohjolainen | 1df4b66 | 2016-08-29 08:57:31 +0300 | [diff] [blame] | 944 | if (!do_single_blorp_clear(brw, fb, rb, buf, partial_clear, |
| 945 | encode_srgb)) { |
| 946 | return false; |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 947 | } |
| 948 | |
| 949 | irb->need_downsample = true; |
| 950 | } |
| 951 | |
| 952 | return true; |
| 953 | } |
| 954 | |
| 955 | void |
Topi Pohjolainen | 9c7717c | 2016-09-15 09:05:55 +0300 | [diff] [blame] | 956 | brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt, |
| 957 | unsigned level, unsigned layer) |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 958 | { |
Topi Pohjolainen | 9c7717c | 2016-09-15 09:05:55 +0300 | [diff] [blame] | 959 | DBG("%s to mt %p level %u layer %u\n", __FUNCTION__, mt, level, layer); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 960 | |
| 961 | const mesa_format format = _mesa_get_srgb_format_linear(mt->format); |
| 962 | |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 963 | struct isl_surf isl_tmp[2]; |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 964 | struct blorp_surf surf; |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 965 | blorp_surf_for_miptree(brw, &surf, mt, true, |
| 966 | (1 << ISL_AUX_USAGE_CCS_E) | |
| 967 | (1 << ISL_AUX_USAGE_CCS_D), |
Topi Pohjolainen | 9c7717c | 2016-09-15 09:05:55 +0300 | [diff] [blame] | 968 | &level, layer, 1 /* num_layers */, |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 969 | isl_tmp); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 970 | |
Jason Ekstrand | 1ba2f05 | 2016-10-25 10:48:12 -0700 | [diff] [blame] | 971 | enum blorp_fast_clear_op resolve_op; |
| 972 | if (brw->gen >= 9) { |
| 973 | if (surf.aux_usage == ISL_AUX_USAGE_CCS_E) |
| 974 | resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL; |
| 975 | else |
| 976 | resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL; |
| 977 | } else { |
| 978 | assert(surf.aux_usage == ISL_AUX_USAGE_CCS_D); |
| 979 | /* Broadwell and earlier do not have a partial resolve */ |
| 980 | resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL; |
| 981 | } |
| 982 | |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 983 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 984 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Topi Pohjolainen | 9c7717c | 2016-09-15 09:05:55 +0300 | [diff] [blame] | 985 | blorp_ccs_resolve(&batch, &surf, level, layer, |
Jason Ekstrand | 1ba2f05 | 2016-10-25 10:48:12 -0700 | [diff] [blame] | 986 | brw_blorp_to_isl_format(brw, format, true), |
| 987 | resolve_op); |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 988 | blorp_batch_finish(&batch); |
Topi Pohjolainen | 9577977 | 2017-01-17 12:00:37 +0200 | [diff] [blame^] | 989 | |
| 990 | /* |
| 991 | * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)": |
| 992 | * |
| 993 | * Any transition from any value in {Clear, Render, Resolve} to a |
| 994 | * different value in {Clear, Render, Resolve} requires end of pipe |
| 995 | * synchronization. |
| 996 | */ |
| 997 | brw_emit_pipe_control_flush(brw, |
| 998 | PIPE_CONTROL_RENDER_TARGET_FLUSH | |
| 999 | PIPE_CONTROL_CS_STALL); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 1000 | } |
| 1001 | |
| 1002 | static void |
| 1003 | gen6_blorp_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt, |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1004 | unsigned int level, unsigned int layer, enum blorp_hiz_op op) |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 1005 | { |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 1006 | assert(intel_miptree_level_has_hiz(mt, level)); |
| 1007 | |
| 1008 | struct isl_surf isl_tmp[2]; |
Jason Ekstrand | 8bd35d8 | 2016-08-19 05:43:29 -0700 | [diff] [blame] | 1009 | struct blorp_surf surf; |
Jason Ekstrand | c8357b5 | 2016-11-16 13:47:13 -0800 | [diff] [blame] | 1010 | blorp_surf_for_miptree(brw, &surf, mt, true, (1 << ISL_AUX_USAGE_HIZ), |
| 1011 | &level, layer, 1, isl_tmp); |
Jason Ekstrand | f5fbcc3 | 2016-08-08 15:25:17 -0700 | [diff] [blame] | 1012 | |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 1013 | struct blorp_batch batch; |
Jason Ekstrand | d80c030 | 2016-10-07 17:20:00 -0700 | [diff] [blame] | 1014 | blorp_batch_init(&brw->blorp, &batch, brw, 0); |
Jason Ekstrand | 2191f5c | 2016-08-19 00:54:56 -0700 | [diff] [blame] | 1015 | blorp_gen6_hiz_op(&batch, &surf, level, layer, op); |
| 1016 | blorp_batch_finish(&batch); |
Jason Ekstrand | 6553dc0 | 2016-06-10 12:03:18 -0700 | [diff] [blame] | 1017 | } |
| 1018 | |
Jason Ekstrand | 8096ed7 | 2016-04-22 13:46:25 -0700 | [diff] [blame] | 1019 | /** |
| 1020 | * Perform a HiZ or depth resolve operation. |
| 1021 | * |
| 1022 | * For an overview of HiZ ops, see the following sections of the Sandy Bridge |
| 1023 | * PRM, Volume 1, Part 2: |
| 1024 | * - 7.5.3.1 Depth Buffer Clear |
| 1025 | * - 7.5.3.2 Depth Buffer Resolve |
| 1026 | * - 7.5.3.3 Hierarchical Depth Buffer Resolve |
| 1027 | */ |
Eric Anholt | 5b226ad | 2012-05-21 09:30:35 -0700 | [diff] [blame] | 1028 | void |
Kenneth Graunke | ca43757 | 2013-07-02 23:17:14 -0700 | [diff] [blame] | 1029 | intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt, |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1030 | unsigned int level, unsigned int layer, enum blorp_hiz_op op) |
Eric Anholt | 5b226ad | 2012-05-21 09:30:35 -0700 | [diff] [blame] | 1031 | { |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1032 | const char *opname = NULL; |
| 1033 | |
| 1034 | switch (op) { |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1035 | case BLORP_HIZ_OP_DEPTH_RESOLVE: |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1036 | opname = "depth resolve"; |
| 1037 | break; |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1038 | case BLORP_HIZ_OP_HIZ_RESOLVE: |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1039 | opname = "hiz ambiguate"; |
| 1040 | break; |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1041 | case BLORP_HIZ_OP_DEPTH_CLEAR: |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1042 | opname = "depth clear"; |
| 1043 | break; |
Jason Ekstrand | 87a1cb6 | 2016-08-19 03:15:41 -0700 | [diff] [blame] | 1044 | case BLORP_HIZ_OP_NONE: |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1045 | opname = "noop?"; |
| 1046 | break; |
| 1047 | } |
| 1048 | |
| 1049 | DBG("%s %s to mt %p level %d layer %d\n", |
Marius Predut | 28d9e90 | 2015-04-07 22:05:28 +0300 | [diff] [blame] | 1050 | __func__, opname, mt, level, layer); |
Eric Anholt | a2ca98b | 2013-05-30 14:53:55 -0700 | [diff] [blame] | 1051 | |
Kenneth Graunke | 8cad1c1 | 2014-02-06 17:06:12 -0800 | [diff] [blame] | 1052 | if (brw->gen >= 8) { |
| 1053 | gen8_hiz_exec(brw, mt, level, layer, op); |
| 1054 | } else { |
Jason Ekstrand | 8096ed7 | 2016-04-22 13:46:25 -0700 | [diff] [blame] | 1055 | gen6_blorp_hiz_exec(brw, mt, level, layer, op); |
Kenneth Graunke | 8cad1c1 | 2014-02-06 17:06:12 -0800 | [diff] [blame] | 1056 | } |
Eric Anholt | 5b226ad | 2012-05-21 09:30:35 -0700 | [diff] [blame] | 1057 | } |