17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2017 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice shall be included
127ec681f3Smrg * in all copies or substantial portions of the Software.
137ec681f3Smrg *
147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
157ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
177ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
187ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
197ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
207ec681f3Smrg * DEALINGS IN THE SOFTWARE.
217ec681f3Smrg */
227ec681f3Smrg
237ec681f3Smrg#include <stdio.h>
247ec681f3Smrg#include <errno.h>
257ec681f3Smrg#include "pipe/p_defines.h"
267ec681f3Smrg#include "pipe/p_state.h"
277ec681f3Smrg#include "pipe/p_context.h"
287ec681f3Smrg#include "pipe/p_screen.h"
297ec681f3Smrg#include "util/u_inlines.h"
307ec681f3Smrg#include "util/u_surface.h"
317ec681f3Smrg#include "util/format/u_format.h"
327ec681f3Smrg#include "util/u_upload_mgr.h"
337ec681f3Smrg#include "util/ralloc.h"
347ec681f3Smrg#include "crocus_context.h"
357ec681f3Smrg#include "crocus_resource.h"
367ec681f3Smrg#include "crocus_screen.h"
377ec681f3Smrg#include "intel/compiler/brw_compiler.h"
387ec681f3Smrg#include "util/format_srgb.h"
397ec681f3Smrg
407ec681f3Smrgstatic bool
417ec681f3Smrgcrocus_is_color_fast_clear_compatible(struct crocus_context *ice,
427ec681f3Smrg                                      enum isl_format format,
437ec681f3Smrg                                      const union isl_color_value color)
447ec681f3Smrg{
457ec681f3Smrg   if (isl_format_has_int_channel(format)) {
467ec681f3Smrg      perf_debug(&ice->dbg, "Integer fast clear not enabled for %s",
477ec681f3Smrg                 isl_format_get_name(format));
487ec681f3Smrg      return false;
497ec681f3Smrg   }
507ec681f3Smrg
517ec681f3Smrg   for (int i = 0; i < 4; i++) {
527ec681f3Smrg      if (!isl_format_has_color_component(format, i)) {
537ec681f3Smrg         continue;
547ec681f3Smrg      }
557ec681f3Smrg
567ec681f3Smrg      if (color.f32[i] != 0.0f && color.f32[i] != 1.0f) {
577ec681f3Smrg         return false;
587ec681f3Smrg      }
597ec681f3Smrg   }
607ec681f3Smrg
617ec681f3Smrg   return true;
627ec681f3Smrg}
637ec681f3Smrg
647ec681f3Smrgstatic bool
657ec681f3Smrgcan_fast_clear_color(struct crocus_context *ice,
667ec681f3Smrg                     struct pipe_resource *p_res,
677ec681f3Smrg                     unsigned level,
687ec681f3Smrg                     const struct pipe_box *box,
697ec681f3Smrg                     bool render_condition_enabled,
707ec681f3Smrg                     enum isl_format format,
717ec681f3Smrg                     enum isl_format render_format,
727ec681f3Smrg                     union isl_color_value color)
737ec681f3Smrg{
747ec681f3Smrg   struct crocus_resource *res = (void *) p_res;
757ec681f3Smrg
767ec681f3Smrg   if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
777ec681f3Smrg      return false;
787ec681f3Smrg
797ec681f3Smrg   if (!isl_aux_usage_has_fast_clears(res->aux.usage))
807ec681f3Smrg      return false;
817ec681f3Smrg
827ec681f3Smrg   /* Check for partial clear */
837ec681f3Smrg   if (box->x > 0 || box->y > 0 ||
847ec681f3Smrg       box->width < minify(p_res->width0, level) ||
857ec681f3Smrg       box->height < minify(p_res->height0, level)) {
867ec681f3Smrg      return false;
877ec681f3Smrg   }
887ec681f3Smrg
897ec681f3Smrg   /* Avoid conditional fast clears to maintain correct tracking of the aux
907ec681f3Smrg    * state (see iris_resource_finish_write for more info). Note that partial
917ec681f3Smrg    * fast clears (if they existed) would not pose a problem with conditional
927ec681f3Smrg    * rendering.
937ec681f3Smrg    */
947ec681f3Smrg   if (render_condition_enabled &&
957ec681f3Smrg       ice->state.predicate == CROCUS_PREDICATE_STATE_USE_BIT) {
967ec681f3Smrg      return false;
977ec681f3Smrg   }
987ec681f3Smrg
997ec681f3Smrg   /* We store clear colors as floats or uints as needed.  If there are
1007ec681f3Smrg    * texture views in play, the formats will not properly be respected
1017ec681f3Smrg    * during resolves because the resolve operations only know about the
1027ec681f3Smrg    * resource and not the renderbuffer.
1037ec681f3Smrg    */
1047ec681f3Smrg   if (isl_format_srgb_to_linear(render_format) !=
1057ec681f3Smrg       isl_format_srgb_to_linear(format)) {
1067ec681f3Smrg      return false;
1077ec681f3Smrg   }
1087ec681f3Smrg
1097ec681f3Smrg   /* XXX: if (irb->mt->supports_fast_clear)
1107ec681f3Smrg    * see intel_miptree_create_for_dri_image()
1117ec681f3Smrg    */
1127ec681f3Smrg
1137ec681f3Smrg   if (!crocus_is_color_fast_clear_compatible(ice, format, color))
1147ec681f3Smrg      return false;
1157ec681f3Smrg
1167ec681f3Smrg   return true;
1177ec681f3Smrg}
1187ec681f3Smrg
1197ec681f3Smrgstatic union isl_color_value
1207ec681f3Smrgconvert_fast_clear_color(struct crocus_context *ice,
1217ec681f3Smrg                         struct crocus_resource *res,
1227ec681f3Smrg                         enum isl_format render_format,
1237ec681f3Smrg                         const union isl_color_value color)
1247ec681f3Smrg{
1257ec681f3Smrg   union isl_color_value override_color = color;
1267ec681f3Smrg   struct pipe_resource *p_res = (void *) res;
1277ec681f3Smrg
1287ec681f3Smrg   const enum pipe_format format = p_res->format;
1297ec681f3Smrg   const struct util_format_description *desc =
1307ec681f3Smrg      util_format_description(format);
1317ec681f3Smrg   unsigned colormask = util_format_colormask(desc);
1327ec681f3Smrg
1337ec681f3Smrg   if (util_format_is_intensity(format) ||
1347ec681f3Smrg       util_format_is_luminance(format) ||
1357ec681f3Smrg       util_format_is_luminance_alpha(format)) {
1367ec681f3Smrg      override_color.u32[1] = override_color.u32[0];
1377ec681f3Smrg      override_color.u32[2] = override_color.u32[0];
1387ec681f3Smrg      if (util_format_is_intensity(format))
1397ec681f3Smrg         override_color.u32[3] = override_color.u32[0];
1407ec681f3Smrg   } else {
1417ec681f3Smrg      for (int chan = 0; chan < 3; chan++) {
1427ec681f3Smrg         if (!(colormask & (1 << chan)))
1437ec681f3Smrg            override_color.u32[chan] = 0;
1447ec681f3Smrg      }
1457ec681f3Smrg   }
1467ec681f3Smrg
1477ec681f3Smrg   if (util_format_is_unorm(format)) {
1487ec681f3Smrg      for (int i = 0; i < 4; i++)
1497ec681f3Smrg         override_color.f32[i] = CLAMP(override_color.f32[i], 0.0f, 1.0f);
1507ec681f3Smrg   } else if (util_format_is_snorm(format)) {
1517ec681f3Smrg      for (int i = 0; i < 4; i++)
1527ec681f3Smrg         override_color.f32[i] = CLAMP(override_color.f32[i], -1.0f, 1.0f);
1537ec681f3Smrg   } else if (util_format_is_pure_uint(format)) {
1547ec681f3Smrg      for (int i = 0; i < 4; i++) {
1557ec681f3Smrg         unsigned bits = util_format_get_component_bits(
1567ec681f3Smrg            format, UTIL_FORMAT_COLORSPACE_RGB, i);
1577ec681f3Smrg         if (bits < 32) {
1587ec681f3Smrg            uint32_t max = (1u << bits) - 1;
1597ec681f3Smrg            override_color.u32[i] = MIN2(override_color.u32[i], max);
1607ec681f3Smrg         }
1617ec681f3Smrg      }
1627ec681f3Smrg   } else if (util_format_is_pure_sint(format)) {
1637ec681f3Smrg      for (int i = 0; i < 4; i++) {
1647ec681f3Smrg         unsigned bits = util_format_get_component_bits(
1657ec681f3Smrg            format, UTIL_FORMAT_COLORSPACE_RGB, i);
1667ec681f3Smrg         if (bits < 32) {
1677ec681f3Smrg            int32_t max = (1 << (bits - 1)) - 1;
1687ec681f3Smrg            int32_t min = -(1 << (bits - 1));
1697ec681f3Smrg            override_color.i32[i] = CLAMP(override_color.i32[i], min, max);
1707ec681f3Smrg         }
1717ec681f3Smrg      }
1727ec681f3Smrg   } else if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
1737ec681f3Smrg              format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
1747ec681f3Smrg      /* these packed float formats only store unsigned values */
1757ec681f3Smrg      for (int i = 0; i < 4; i++)
1767ec681f3Smrg         override_color.f32[i] = MAX2(override_color.f32[i], 0.0f);
1777ec681f3Smrg   }
1787ec681f3Smrg
1797ec681f3Smrg   if (!(colormask & 1 << 3)) {
1807ec681f3Smrg      if (util_format_is_pure_integer(format))
1817ec681f3Smrg         override_color.u32[3] = 1;
1827ec681f3Smrg      else
1837ec681f3Smrg         override_color.f32[3] = 1.0f;
1847ec681f3Smrg   }
1857ec681f3Smrg
1867ec681f3Smrg   /* Handle linear to SRGB conversion */
1877ec681f3Smrg   if (isl_format_is_srgb(render_format)) {
1887ec681f3Smrg      for (int i = 0; i < 3; i++) {
1897ec681f3Smrg         override_color.f32[i] =
1907ec681f3Smrg            util_format_linear_to_srgb_float(override_color.f32[i]);
1917ec681f3Smrg      }
1927ec681f3Smrg   }
1937ec681f3Smrg
1947ec681f3Smrg   return override_color;
1957ec681f3Smrg}
1967ec681f3Smrg
1977ec681f3Smrgstatic void
1987ec681f3Smrgfast_clear_color(struct crocus_context *ice,
1997ec681f3Smrg                 struct crocus_resource *res,
2007ec681f3Smrg                 unsigned level,
2017ec681f3Smrg                 const struct pipe_box *box,
2027ec681f3Smrg                 enum isl_format format,
2037ec681f3Smrg                 union isl_color_value color,
2047ec681f3Smrg                 enum blorp_batch_flags blorp_flags)
2057ec681f3Smrg{
2067ec681f3Smrg   struct crocus_batch *batch = &ice->batches[CROCUS_BATCH_RENDER];
2077ec681f3Smrg   struct crocus_screen *screen = batch->screen;
2087ec681f3Smrg   struct pipe_resource *p_res = (void *) res;
2097ec681f3Smrg
2107ec681f3Smrg   color = convert_fast_clear_color(ice, res, format, color);
2117ec681f3Smrg
2127ec681f3Smrg   bool color_changed = !!memcmp(&res->aux.clear_color, &color,
2137ec681f3Smrg                                 sizeof(color));
2147ec681f3Smrg
2157ec681f3Smrg   if (color_changed) {
2167ec681f3Smrg      /* If we are clearing to a new clear value, we need to resolve fast
2177ec681f3Smrg       * clears from other levels/layers first, since we can't have different
2187ec681f3Smrg       * levels/layers with different fast clear colors.
2197ec681f3Smrg       */
2207ec681f3Smrg      for (unsigned res_lvl = 0; res_lvl < res->surf.levels; res_lvl++) {
2217ec681f3Smrg         const unsigned level_layers =
2227ec681f3Smrg            crocus_get_num_logical_layers(res, res_lvl);
2237ec681f3Smrg         for (unsigned layer = 0; layer < level_layers; layer++) {
2247ec681f3Smrg            if (res_lvl == level &&
2257ec681f3Smrg                layer >= box->z &&
2267ec681f3Smrg                layer < box->z + box->depth) {
2277ec681f3Smrg               /* We're going to clear this layer anyway.  Leave it alone. */
2287ec681f3Smrg               continue;
2297ec681f3Smrg            }
2307ec681f3Smrg
2317ec681f3Smrg            enum isl_aux_state aux_state =
2327ec681f3Smrg               crocus_resource_get_aux_state(res, res_lvl, layer);
2337ec681f3Smrg
2347ec681f3Smrg            if (aux_state != ISL_AUX_STATE_CLEAR &&
2357ec681f3Smrg                aux_state != ISL_AUX_STATE_PARTIAL_CLEAR &&
2367ec681f3Smrg                aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
2377ec681f3Smrg               /* This slice doesn't have any fast-cleared bits. */
2387ec681f3Smrg               continue;
2397ec681f3Smrg            }
2407ec681f3Smrg
2417ec681f3Smrg            /* If we got here, then the level may have fast-clear bits that use
2427ec681f3Smrg             * the old clear value.  We need to do a color resolve to get rid
2437ec681f3Smrg             * of their use of the clear color before we can change it.
2447ec681f3Smrg             * Fortunately, few applications ever change their clear color at
2457ec681f3Smrg             * different levels/layers, so this shouldn't happen often.
2467ec681f3Smrg             */
2477ec681f3Smrg            crocus_resource_prepare_access(ice, res,
2487ec681f3Smrg                                           res_lvl, 1, layer, 1,
2497ec681f3Smrg                                           res->aux.usage,
2507ec681f3Smrg                                           false);
2517ec681f3Smrg            perf_debug(&ice->dbg,
2527ec681f3Smrg                       "Resolving resource (%p) level %d, layer %d: color changing from "
2537ec681f3Smrg                       "(%0.2f, %0.2f, %0.2f, %0.2f) to "
2547ec681f3Smrg                       "(%0.2f, %0.2f, %0.2f, %0.2f)\n",
2557ec681f3Smrg                       res, res_lvl, layer,
2567ec681f3Smrg                       res->aux.clear_color.f32[0],
2577ec681f3Smrg                       res->aux.clear_color.f32[1],
2587ec681f3Smrg                       res->aux.clear_color.f32[2],
2597ec681f3Smrg                       res->aux.clear_color.f32[3],
2607ec681f3Smrg                       color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
2617ec681f3Smrg         }
2627ec681f3Smrg      }
2637ec681f3Smrg   }
2647ec681f3Smrg
2657ec681f3Smrg   crocus_resource_set_clear_color(ice, res, color);
2667ec681f3Smrg
2677ec681f3Smrg   /* If the buffer is already in ISL_AUX_STATE_CLEAR, and the color hasn't
2687ec681f3Smrg    * changed, the clear is redundant and can be skipped.
2697ec681f3Smrg    */
2707ec681f3Smrg   const enum isl_aux_state aux_state =
2717ec681f3Smrg      crocus_resource_get_aux_state(res, level, box->z);
2727ec681f3Smrg   if (!color_changed && box->depth == 1 && aux_state == ISL_AUX_STATE_CLEAR)
2737ec681f3Smrg      return;
2747ec681f3Smrg
2757ec681f3Smrg   /* Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
2767ec681f3Smrg    *
2777ec681f3Smrg    *    "Any transition from any value in {Clear, Render, Resolve} to a
2787ec681f3Smrg    *    different value in {Clear, Render, Resolve} requires end of pipe
2797ec681f3Smrg    *    synchronization."
2807ec681f3Smrg    *
2817ec681f3Smrg    * In other words, fast clear ops are not properly synchronized with
2827ec681f3Smrg    * other drawing.  We need to use a PIPE_CONTROL to ensure that the
2837ec681f3Smrg    * contents of the previous draw hit the render target before we resolve
2847ec681f3Smrg    * and again afterwards to ensure that the resolve is complete before we
2857ec681f3Smrg    * do any more regular drawing.
2867ec681f3Smrg    */
2877ec681f3Smrg   crocus_emit_end_of_pipe_sync(batch,
2887ec681f3Smrg                                "fast clear: pre-flush",
2897ec681f3Smrg                                PIPE_CONTROL_RENDER_TARGET_FLUSH);
2907ec681f3Smrg
2917ec681f3Smrg   /* If we reach this point, we need to fast clear to change the state to
2927ec681f3Smrg    * ISL_AUX_STATE_CLEAR, or to update the fast clear color (or both).
2937ec681f3Smrg    */
2947ec681f3Smrg   blorp_flags |= color_changed ? 0 : BLORP_BATCH_NO_UPDATE_CLEAR_COLOR;
2957ec681f3Smrg
2967ec681f3Smrg   struct blorp_batch blorp_batch;
2977ec681f3Smrg   blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
2987ec681f3Smrg
2997ec681f3Smrg   struct blorp_surf surf;
3007ec681f3Smrg   crocus_blorp_surf_for_resource(&screen->vtbl, &batch->screen->isl_dev, &surf,
3017ec681f3Smrg                                  p_res, res->aux.usage, level, true);
3027ec681f3Smrg
3037ec681f3Smrg   /* In newer gens (> 9), the hardware will do a linear -> sRGB conversion of
3047ec681f3Smrg    * the clear color during the fast clear, if the surface format is of sRGB
3057ec681f3Smrg    * type. We use the linear version of the surface format here to prevent
3067ec681f3Smrg    * that from happening, since we already do our own linear -> sRGB
3077ec681f3Smrg    * conversion in convert_fast_clear_color().
3087ec681f3Smrg    */
3097ec681f3Smrg   blorp_fast_clear(&blorp_batch, &surf, isl_format_srgb_to_linear(format),
3107ec681f3Smrg                    ISL_SWIZZLE_IDENTITY,
3117ec681f3Smrg                    level, box->z, box->depth,
3127ec681f3Smrg                    box->x, box->y, box->x + box->width,
3137ec681f3Smrg                    box->y + box->height);
3147ec681f3Smrg   blorp_batch_finish(&blorp_batch);
3157ec681f3Smrg   crocus_emit_end_of_pipe_sync(batch,
3167ec681f3Smrg                                "fast clear: post flush",
3177ec681f3Smrg                                PIPE_CONTROL_RENDER_TARGET_FLUSH);
3187ec681f3Smrg
3197ec681f3Smrg   crocus_resource_set_aux_state(ice, res, level, box->z,
3207ec681f3Smrg                                 box->depth, ISL_AUX_STATE_CLEAR);
3217ec681f3Smrg   ice->state.stage_dirty |= CROCUS_ALL_STAGE_DIRTY_BINDINGS;
3227ec681f3Smrg   return;
3237ec681f3Smrg}
3247ec681f3Smrg
3257ec681f3Smrgstatic void
3267ec681f3Smrgclear_color(struct crocus_context *ice,
3277ec681f3Smrg            struct pipe_resource *p_res,
3287ec681f3Smrg            unsigned level,
3297ec681f3Smrg            const struct pipe_box *box,
3307ec681f3Smrg            bool render_condition_enabled,
3317ec681f3Smrg            enum isl_format format,
3327ec681f3Smrg            struct isl_swizzle swizzle,
3337ec681f3Smrg            union isl_color_value color)
3347ec681f3Smrg{
3357ec681f3Smrg   struct crocus_resource *res = (void *) p_res;
3367ec681f3Smrg   struct crocus_batch *batch = &ice->batches[CROCUS_BATCH_RENDER];
3377ec681f3Smrg   struct crocus_screen *screen = batch->screen;
3387ec681f3Smrg   const struct intel_device_info *devinfo = &batch->screen->devinfo;
3397ec681f3Smrg   enum blorp_batch_flags blorp_flags = 0;
3407ec681f3Smrg
3417ec681f3Smrg   if (render_condition_enabled) {
3427ec681f3Smrg      if (!crocus_check_conditional_render(ice))
3437ec681f3Smrg         return;
3447ec681f3Smrg
3457ec681f3Smrg      if (ice->state.predicate == CROCUS_PREDICATE_STATE_USE_BIT)
3467ec681f3Smrg         blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
3477ec681f3Smrg   }
3487ec681f3Smrg
3497ec681f3Smrg   if (p_res->target == PIPE_BUFFER)
3507ec681f3Smrg      util_range_add(&res->base.b, &res->valid_buffer_range, box->x, box->x + box->width);
3517ec681f3Smrg
3527ec681f3Smrg   crocus_batch_maybe_flush(batch, 1500);
3537ec681f3Smrg
3547ec681f3Smrg   bool can_fast_clear = can_fast_clear_color(ice, p_res, level, box,
3557ec681f3Smrg                                              render_condition_enabled,
3567ec681f3Smrg                                              res->surf.format, format, color);
3577ec681f3Smrg   if (can_fast_clear) {
3587ec681f3Smrg      fast_clear_color(ice, res, level, box, format, color,
3597ec681f3Smrg                       blorp_flags);
3607ec681f3Smrg      return;
3617ec681f3Smrg   }
3627ec681f3Smrg
3637ec681f3Smrg   enum isl_aux_usage aux_usage =
3647ec681f3Smrg      crocus_resource_render_aux_usage(ice, res, level, format, false);
3657ec681f3Smrg
3667ec681f3Smrg   crocus_resource_prepare_render(ice, res, level,
3677ec681f3Smrg                                  box->z, box->depth, aux_usage);
3687ec681f3Smrg
3697ec681f3Smrg   struct blorp_surf surf;
3707ec681f3Smrg   crocus_blorp_surf_for_resource(&screen->vtbl, &batch->screen->isl_dev, &surf,
3717ec681f3Smrg                                  p_res, aux_usage, level, true);
3727ec681f3Smrg
3737ec681f3Smrg   struct blorp_batch blorp_batch;
3747ec681f3Smrg   blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
3757ec681f3Smrg
3767ec681f3Smrg   if (!isl_format_supports_rendering(devinfo, format) &&
3777ec681f3Smrg       isl_format_is_rgbx(format))
3787ec681f3Smrg      format = isl_format_rgbx_to_rgba(format);
3797ec681f3Smrg
3807ec681f3Smrg   blorp_clear(&blorp_batch, &surf, format, swizzle,
3817ec681f3Smrg               level, box->z, box->depth, box->x, box->y,
3827ec681f3Smrg               box->x + box->width, box->y + box->height,
3837ec681f3Smrg               color, 0 /* color_write_disable */);
3847ec681f3Smrg
3857ec681f3Smrg   blorp_batch_finish(&blorp_batch);
3867ec681f3Smrg   crocus_flush_and_dirty_for_history(ice, batch, res,
3877ec681f3Smrg                                      PIPE_CONTROL_RENDER_TARGET_FLUSH,
3887ec681f3Smrg                                      "cache history: post color clear");
3897ec681f3Smrg
3907ec681f3Smrg   crocus_resource_finish_render(ice, res, level,
3917ec681f3Smrg                                 box->z, box->depth, aux_usage);
3927ec681f3Smrg}
3937ec681f3Smrg
3947ec681f3Smrgstatic bool
3957ec681f3Smrgcan_fast_clear_depth(struct crocus_context *ice,
3967ec681f3Smrg                     struct crocus_resource *res,
3977ec681f3Smrg                     unsigned level,
3987ec681f3Smrg                     const struct pipe_box *box,
3997ec681f3Smrg                     bool render_condition_enabled,
4007ec681f3Smrg                     float depth)
4017ec681f3Smrg{
4027ec681f3Smrg   struct pipe_resource *p_res = (void *) res;
4037ec681f3Smrg   struct pipe_context *ctx = (void *) ice;
4047ec681f3Smrg   struct crocus_screen *screen = (void *) ctx->screen;
4057ec681f3Smrg   const struct intel_device_info *devinfo = &screen->devinfo;
4067ec681f3Smrg
4077ec681f3Smrg   if (devinfo->ver < 6)
4087ec681f3Smrg      return false;
4097ec681f3Smrg
4107ec681f3Smrg   if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR))
4117ec681f3Smrg      return false;
4127ec681f3Smrg
4137ec681f3Smrg   /* Check for partial clears */
4147ec681f3Smrg   if (box->x > 0 || box->y > 0 ||
4157ec681f3Smrg       box->width < u_minify(p_res->width0, level) ||
4167ec681f3Smrg       box->height < u_minify(p_res->height0, level)) {
4177ec681f3Smrg      return false;
4187ec681f3Smrg   }
4197ec681f3Smrg
4207ec681f3Smrg   /* Avoid conditional fast clears to maintain correct tracking of the aux
4217ec681f3Smrg    * state (see iris_resource_finish_write for more info). Note that partial
4227ec681f3Smrg    * fast clears would not pose a problem with conditional rendering.
4237ec681f3Smrg    */
4247ec681f3Smrg   if (render_condition_enabled &&
4257ec681f3Smrg       ice->state.predicate == CROCUS_PREDICATE_STATE_USE_BIT) {
4267ec681f3Smrg      return false;
4277ec681f3Smrg   }
4287ec681f3Smrg
4297ec681f3Smrg   if (!crocus_resource_level_has_hiz(res, level))
4307ec681f3Smrg      return false;
4317ec681f3Smrg
4327ec681f3Smrg   if (res->base.b.format == PIPE_FORMAT_Z16_UNORM) {
4337ec681f3Smrg      /* From the Sandy Bridge PRM, volume 2 part 1, page 314:
4347ec681f3Smrg       *
4357ec681f3Smrg       *     "[DevSNB+]: Several cases exist where Depth Buffer Clear cannot be
4367ec681f3Smrg       *      enabled (the legacy method of clearing must be performed):
4377ec681f3Smrg       *
4387ec681f3Smrg       *      - DevSNB{W/A}]: When depth buffer format is D16_UNORM and the
4397ec681f3Smrg       *        width of the map (LOD0) is not multiple of 16, fast clear
4407ec681f3Smrg       *        optimization must be disabled.
4417ec681f3Smrg       */
4427ec681f3Smrg      if (devinfo->ver == 6 &&
4437ec681f3Smrg          (minify(res->surf.phys_level0_sa.width,
4447ec681f3Smrg                  level) % 16) != 0)
4457ec681f3Smrg         return false;
4467ec681f3Smrg   }
4477ec681f3Smrg   return true;
4487ec681f3Smrg}
4497ec681f3Smrg
4507ec681f3Smrgstatic void
4517ec681f3Smrgfast_clear_depth(struct crocus_context *ice,
4527ec681f3Smrg                 struct crocus_resource *res,
4537ec681f3Smrg                 unsigned level,
4547ec681f3Smrg                 const struct pipe_box *box,
4557ec681f3Smrg                 float depth)
4567ec681f3Smrg{
4577ec681f3Smrg   struct pipe_resource *p_res = (void *) res;
4587ec681f3Smrg   struct crocus_batch *batch = &ice->batches[CROCUS_BATCH_RENDER];
4597ec681f3Smrg
4607ec681f3Smrg   /* Quantize the clear value to what can be stored in the actual depth
4617ec681f3Smrg    * buffer.  This makes the following check more accurate because it now
4627ec681f3Smrg    * checks if the actual depth bits will match.  It also prevents us from
4637ec681f3Smrg    * getting a too-accurate depth value during depth testing or when sampling
4647ec681f3Smrg    * with HiZ enabled.
4657ec681f3Smrg    */
4667ec681f3Smrg   const unsigned nbits = p_res->format == PIPE_FORMAT_Z16_UNORM ? 16 : 24;
4677ec681f3Smrg   const uint32_t depth_max = (1 << nbits) - 1;
4687ec681f3Smrg   depth = p_res->format == PIPE_FORMAT_Z32_FLOAT ? depth :
4697ec681f3Smrg      (unsigned)(depth * depth_max) / (float)depth_max;
4707ec681f3Smrg
4717ec681f3Smrg   bool update_clear_depth = false;
4727ec681f3Smrg
4737ec681f3Smrg   /* If we're clearing to a new clear value, then we need to resolve any clear
4747ec681f3Smrg    * flags out of the HiZ buffer into the real depth buffer.
4757ec681f3Smrg    */
4767ec681f3Smrg   if (res->aux.clear_color.f32[0] != depth) {
4777ec681f3Smrg      for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
4787ec681f3Smrg         if (!crocus_resource_level_has_hiz(res, res_level))
4797ec681f3Smrg            continue;
4807ec681f3Smrg
4817ec681f3Smrg         const unsigned level_layers =
4827ec681f3Smrg            crocus_get_num_logical_layers(res, res_level);
4837ec681f3Smrg         for (unsigned layer = 0; layer < level_layers; layer++) {
4847ec681f3Smrg            if (res_level == level &&
4857ec681f3Smrg                layer >= box->z &&
4867ec681f3Smrg                layer < box->z + box->depth) {
4877ec681f3Smrg               /* We're going to clear this layer anyway.  Leave it alone. */
4887ec681f3Smrg               continue;
4897ec681f3Smrg            }
4907ec681f3Smrg
4917ec681f3Smrg            enum isl_aux_state aux_state =
4927ec681f3Smrg               crocus_resource_get_aux_state(res, res_level, layer);
4937ec681f3Smrg
4947ec681f3Smrg            if (aux_state != ISL_AUX_STATE_CLEAR &&
4957ec681f3Smrg                aux_state != ISL_AUX_STATE_COMPRESSED_CLEAR) {
4967ec681f3Smrg               /* This slice doesn't have any fast-cleared bits. */
4977ec681f3Smrg               continue;
4987ec681f3Smrg            }
4997ec681f3Smrg
5007ec681f3Smrg            /* If we got here, then the level may have fast-clear bits that
5017ec681f3Smrg             * use the old clear value.  We need to do a depth resolve to get
5027ec681f3Smrg             * rid of their use of the clear value before we can change it.
5037ec681f3Smrg             * Fortunately, few applications ever change their depth clear
5047ec681f3Smrg             * value so this shouldn't happen often.
5057ec681f3Smrg             */
5067ec681f3Smrg            crocus_hiz_exec(ice, batch, res, res_level, layer, 1,
5077ec681f3Smrg                            ISL_AUX_OP_FULL_RESOLVE, false);
5087ec681f3Smrg            crocus_resource_set_aux_state(ice, res, res_level, layer, 1,
5097ec681f3Smrg                                          ISL_AUX_STATE_RESOLVED);
5107ec681f3Smrg         }
5117ec681f3Smrg      }
5127ec681f3Smrg      const union isl_color_value clear_value = { .f32 = {depth, } };
5137ec681f3Smrg      crocus_resource_set_clear_color(ice, res, clear_value);
5147ec681f3Smrg      update_clear_depth = true;
5157ec681f3Smrg   }
5167ec681f3Smrg
5177ec681f3Smrg   for (unsigned l = 0; l < box->depth; l++) {
5187ec681f3Smrg      enum isl_aux_state aux_state =
5197ec681f3Smrg         crocus_resource_level_has_hiz(res, level) ?
5207ec681f3Smrg         crocus_resource_get_aux_state(res, level, box->z + l) :
5217ec681f3Smrg         ISL_AUX_STATE_AUX_INVALID;
5227ec681f3Smrg      if (update_clear_depth || aux_state != ISL_AUX_STATE_CLEAR) {
5237ec681f3Smrg         if (aux_state == ISL_AUX_STATE_CLEAR) {
5247ec681f3Smrg            perf_debug(&ice->dbg, "Performing HiZ clear just to update the "
5257ec681f3Smrg                       "depth clear value\n");
5267ec681f3Smrg         }
5277ec681f3Smrg         crocus_hiz_exec(ice, batch, res, level,
5287ec681f3Smrg                         box->z + l, 1, ISL_AUX_OP_FAST_CLEAR,
5297ec681f3Smrg                         update_clear_depth);
5307ec681f3Smrg      }
5317ec681f3Smrg   }
5327ec681f3Smrg
5337ec681f3Smrg   crocus_resource_set_aux_state(ice, res, level, box->z, box->depth,
5347ec681f3Smrg                                 ISL_AUX_STATE_CLEAR);
5357ec681f3Smrg   ice->state.dirty |= CROCUS_DIRTY_DEPTH_BUFFER;
5367ec681f3Smrg}
5377ec681f3Smrg
5387ec681f3Smrgstatic void
5397ec681f3Smrgclear_depth_stencil(struct crocus_context *ice,
5407ec681f3Smrg                    struct pipe_resource *p_res,
5417ec681f3Smrg                    unsigned level,
5427ec681f3Smrg                    const struct pipe_box *box,
5437ec681f3Smrg                    bool render_condition_enabled,
5447ec681f3Smrg                    bool clear_depth,
5457ec681f3Smrg                    bool clear_stencil,
5467ec681f3Smrg                    float depth,
5477ec681f3Smrg                    uint8_t stencil)
5487ec681f3Smrg{
5497ec681f3Smrg   struct crocus_resource *res = (void *) p_res;
5507ec681f3Smrg   struct crocus_batch *batch = &ice->batches[CROCUS_BATCH_RENDER];
5517ec681f3Smrg   struct crocus_screen *screen = batch->screen;
5527ec681f3Smrg   enum blorp_batch_flags blorp_flags = 0;
5537ec681f3Smrg
5547ec681f3Smrg   if (render_condition_enabled) {
5557ec681f3Smrg      if (!crocus_check_conditional_render(ice))
5567ec681f3Smrg         return;
5577ec681f3Smrg
5587ec681f3Smrg      if (ice->state.predicate == CROCUS_PREDICATE_STATE_USE_BIT)
5597ec681f3Smrg         blorp_flags |= BLORP_BATCH_PREDICATE_ENABLE;
5607ec681f3Smrg   }
5617ec681f3Smrg
5627ec681f3Smrg   crocus_batch_maybe_flush(batch, 1500);
5637ec681f3Smrg
5647ec681f3Smrg   struct crocus_resource *z_res;
5657ec681f3Smrg   struct crocus_resource *stencil_res;
5667ec681f3Smrg   struct blorp_surf z_surf;
5677ec681f3Smrg   struct blorp_surf stencil_surf;
5687ec681f3Smrg
5697ec681f3Smrg   crocus_get_depth_stencil_resources(&batch->screen->devinfo, p_res, &z_res, &stencil_res);
5707ec681f3Smrg   if (z_res && clear_depth &&
5717ec681f3Smrg       can_fast_clear_depth(ice, z_res, level, box, render_condition_enabled,
5727ec681f3Smrg                            depth)) {
5737ec681f3Smrg      fast_clear_depth(ice, z_res, level, box, depth);
5747ec681f3Smrg      crocus_flush_and_dirty_for_history(ice, batch, res, 0,
5757ec681f3Smrg                                         "cache history: post fast Z clear");
5767ec681f3Smrg      clear_depth = false;
5777ec681f3Smrg      z_res = NULL;
5787ec681f3Smrg   }
5797ec681f3Smrg
5807ec681f3Smrg   /* At this point, we might have fast cleared the depth buffer. So if there's
5817ec681f3Smrg    * no stencil clear pending, return early.
5827ec681f3Smrg    */
5837ec681f3Smrg   if (!(clear_depth || (clear_stencil && stencil_res))) {
5847ec681f3Smrg      return;
5857ec681f3Smrg   }
5867ec681f3Smrg
5877ec681f3Smrg   if (clear_depth && z_res) {
5887ec681f3Smrg      const enum isl_aux_usage aux_usage =
5897ec681f3Smrg         crocus_resource_render_aux_usage(ice, z_res, level, z_res->surf.format,
5907ec681f3Smrg                                          false);
5917ec681f3Smrg      crocus_resource_prepare_render(ice, z_res, level, box->z, box->depth,
5927ec681f3Smrg                                     aux_usage);
5937ec681f3Smrg      crocus_blorp_surf_for_resource(&screen->vtbl, &batch->screen->isl_dev,
5947ec681f3Smrg                                     &z_surf, &z_res->base.b, aux_usage,
5957ec681f3Smrg                                     level, true);
5967ec681f3Smrg   }
5977ec681f3Smrg
5987ec681f3Smrg   struct blorp_batch blorp_batch;
5997ec681f3Smrg   blorp_batch_init(&ice->blorp, &blorp_batch, batch, blorp_flags);
6007ec681f3Smrg
6017ec681f3Smrg   uint8_t stencil_mask = clear_stencil && stencil_res ? 0xff : 0;
6027ec681f3Smrg   if (stencil_mask) {
6037ec681f3Smrg      crocus_resource_prepare_access(ice, stencil_res, level, 1, box->z,
6047ec681f3Smrg                                     box->depth, stencil_res->aux.usage, false);
6057ec681f3Smrg      crocus_blorp_surf_for_resource(&screen->vtbl, &batch->screen->isl_dev,
6067ec681f3Smrg                                     &stencil_surf, &stencil_res->base.b,
6077ec681f3Smrg                                     stencil_res->aux.usage, level, true);
6087ec681f3Smrg   }
6097ec681f3Smrg
6107ec681f3Smrg   blorp_clear_depth_stencil(&blorp_batch, &z_surf, &stencil_surf,
6117ec681f3Smrg                             level, box->z, box->depth,
6127ec681f3Smrg                             box->x, box->y,
6137ec681f3Smrg                             box->x + box->width,
6147ec681f3Smrg                             box->y + box->height,
6157ec681f3Smrg                             clear_depth && z_res, depth,
6167ec681f3Smrg                             stencil_mask, stencil);
6177ec681f3Smrg
6187ec681f3Smrg   blorp_batch_finish(&blorp_batch);
6197ec681f3Smrg   crocus_flush_and_dirty_for_history(ice, batch, res, 0,
6207ec681f3Smrg                                      "cache history: post slow ZS clear");
6217ec681f3Smrg
6227ec681f3Smrg   if (clear_depth && z_res) {
6237ec681f3Smrg      crocus_resource_finish_render(ice, z_res, level,
6247ec681f3Smrg                                    box->z, box->depth, z_surf.aux_usage);
6257ec681f3Smrg   }
6267ec681f3Smrg
6277ec681f3Smrg   if (stencil_mask) {
6287ec681f3Smrg      crocus_resource_finish_write(ice, stencil_res, level, box->z, box->depth,
6297ec681f3Smrg                                   stencil_res->aux.usage);
6307ec681f3Smrg   }
6317ec681f3Smrg}
6327ec681f3Smrg
6337ec681f3Smrg/**
6347ec681f3Smrg * The pipe->clear() driver hook.
6357ec681f3Smrg *
6367ec681f3Smrg * This clears buffers attached to the current draw framebuffer.
6377ec681f3Smrg */
6387ec681f3Smrgstatic void
6397ec681f3Smrgcrocus_clear(struct pipe_context *ctx,
6407ec681f3Smrg             unsigned buffers,
6417ec681f3Smrg             const struct pipe_scissor_state *scissor_state,
6427ec681f3Smrg             const union pipe_color_union *p_color,
6437ec681f3Smrg             double depth,
6447ec681f3Smrg             unsigned stencil)
6457ec681f3Smrg{
6467ec681f3Smrg   struct crocus_context *ice = (void *) ctx;
6477ec681f3Smrg   struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
6487ec681f3Smrg   struct crocus_screen *screen = (void *) ctx->screen;
6497ec681f3Smrg   const struct intel_device_info *devinfo = &screen->devinfo;
6507ec681f3Smrg   assert(buffers != 0);
6517ec681f3Smrg
6527ec681f3Smrg   struct pipe_box box = {
6537ec681f3Smrg      .width = cso_fb->width,
6547ec681f3Smrg      .height = cso_fb->height,
6557ec681f3Smrg   };
6567ec681f3Smrg
6577ec681f3Smrg   if (scissor_state) {
6587ec681f3Smrg      box.x = scissor_state->minx;
6597ec681f3Smrg      box.y = scissor_state->miny;
6607ec681f3Smrg      box.width = MIN2(box.width, scissor_state->maxx - scissor_state->minx);
6617ec681f3Smrg      box.height = MIN2(box.height, scissor_state->maxy - scissor_state->miny);
6627ec681f3Smrg   }
6637ec681f3Smrg
6647ec681f3Smrg   if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
6657ec681f3Smrg      if (devinfo->ver < 6) {
6667ec681f3Smrg         crocus_blitter_begin(ice, CROCUS_SAVE_FRAGMENT_STATE, true);
6677ec681f3Smrg         util_blitter_clear(ice->blitter, cso_fb->width, cso_fb->height,
6687ec681f3Smrg                            util_framebuffer_get_num_layers(cso_fb),
6697ec681f3Smrg                            buffers & PIPE_CLEAR_DEPTHSTENCIL, p_color, depth, stencil, false);
6707ec681f3Smrg      } else {
6717ec681f3Smrg         struct pipe_surface *psurf = cso_fb->zsbuf;
6727ec681f3Smrg         box.depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1;
6737ec681f3Smrg         box.z = psurf->u.tex.first_layer;
6747ec681f3Smrg
6757ec681f3Smrg         clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box, true,
6767ec681f3Smrg                             buffers & PIPE_CLEAR_DEPTH,
6777ec681f3Smrg                             buffers & PIPE_CLEAR_STENCIL,
6787ec681f3Smrg                             depth, stencil);
6797ec681f3Smrg      }
6807ec681f3Smrg      buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
6817ec681f3Smrg   }
6827ec681f3Smrg
6837ec681f3Smrg   if (buffers & PIPE_CLEAR_COLOR) {
6847ec681f3Smrg      /* pipe_color_union and isl_color_value are interchangeable */
6857ec681f3Smrg      union isl_color_value *color = (void *) p_color;
6867ec681f3Smrg
6877ec681f3Smrg      for (unsigned i = 0; i < cso_fb->nr_cbufs; i++) {
6887ec681f3Smrg         if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
6897ec681f3Smrg            struct pipe_surface *psurf = cso_fb->cbufs[i];
6907ec681f3Smrg            struct crocus_surface *isurf = (void *) psurf;
6917ec681f3Smrg            box.depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1,
6927ec681f3Smrg            box.z = psurf->u.tex.first_layer,
6937ec681f3Smrg
6947ec681f3Smrg            clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
6957ec681f3Smrg                        true, isurf->view.format, isurf->view.swizzle,
6967ec681f3Smrg                        *color);
6977ec681f3Smrg         }
6987ec681f3Smrg      }
6997ec681f3Smrg   }
7007ec681f3Smrg}
7017ec681f3Smrg
7027ec681f3Smrg/**
7037ec681f3Smrg * The pipe->clear_texture() driver hook.
7047ec681f3Smrg *
7057ec681f3Smrg * This clears the given texture resource.
7067ec681f3Smrg */
7077ec681f3Smrgstatic void
7087ec681f3Smrgcrocus_clear_texture(struct pipe_context *ctx,
7097ec681f3Smrg                     struct pipe_resource *p_res,
7107ec681f3Smrg                     unsigned level,
7117ec681f3Smrg                     const struct pipe_box *box,
7127ec681f3Smrg                     const void *data)
7137ec681f3Smrg{
7147ec681f3Smrg   struct crocus_context *ice = (void *) ctx;
7157ec681f3Smrg   struct crocus_screen *screen = (void *) ctx->screen;
7167ec681f3Smrg   const struct intel_device_info *devinfo = &screen->devinfo;
7177ec681f3Smrg   struct crocus_resource *res = (void *) p_res;
7187ec681f3Smrg
7197ec681f3Smrg   if (devinfo->ver < 6) {
7207ec681f3Smrg      util_clear_texture(ctx, p_res,
7217ec681f3Smrg                         level, box, data);
7227ec681f3Smrg      return;
7237ec681f3Smrg   }
7247ec681f3Smrg
7257ec681f3Smrg   if (crocus_resource_unfinished_aux_import(res))
7267ec681f3Smrg      crocus_resource_finish_aux_import(ctx->screen, res);
7277ec681f3Smrg
7287ec681f3Smrg   if (util_format_is_depth_or_stencil(p_res->format)) {
7297ec681f3Smrg      const struct util_format_unpack_description *fmt_unpack =
7307ec681f3Smrg         util_format_unpack_description(p_res->format);
7317ec681f3Smrg
7327ec681f3Smrg      float depth = 0.0;
7337ec681f3Smrg      uint8_t stencil = 0;
7347ec681f3Smrg
7357ec681f3Smrg      if (fmt_unpack->unpack_z_float)
7367ec681f3Smrg         fmt_unpack->unpack_z_float(&depth, 0, data, 0, 1, 1);
7377ec681f3Smrg
7387ec681f3Smrg      if (fmt_unpack->unpack_s_8uint)
7397ec681f3Smrg         fmt_unpack->unpack_s_8uint(&stencil, 0, data, 0, 1, 1);
7407ec681f3Smrg
7417ec681f3Smrg      clear_depth_stencil(ice, p_res, level, box, true, true, true,
7427ec681f3Smrg                          depth, stencil);
7437ec681f3Smrg   } else {
7447ec681f3Smrg      union isl_color_value color;
7457ec681f3Smrg      struct crocus_resource *res = (void *) p_res;
7467ec681f3Smrg      enum isl_format format = res->surf.format;
7477ec681f3Smrg
7487ec681f3Smrg      if (!isl_format_supports_rendering(devinfo, format)) {
7497ec681f3Smrg         const struct isl_format_layout *fmtl = isl_format_get_layout(format);
7507ec681f3Smrg         // XXX: actually just get_copy_format_for_bpb from BLORP
7517ec681f3Smrg         // XXX: don't cut and paste this
7527ec681f3Smrg         switch (fmtl->bpb) {
7537ec681f3Smrg         case 8:   format = ISL_FORMAT_R8_UINT;           break;
7547ec681f3Smrg         case 16:  format = ISL_FORMAT_R8G8_UINT;         break;
7557ec681f3Smrg         case 24:  format = ISL_FORMAT_R8G8B8_UINT;       break;
7567ec681f3Smrg         case 32:  format = ISL_FORMAT_R8G8B8A8_UINT;     break;
7577ec681f3Smrg         case 48:  format = ISL_FORMAT_R16G16B16_UINT;    break;
7587ec681f3Smrg         case 64:  format = ISL_FORMAT_R16G16B16A16_UINT; break;
7597ec681f3Smrg         case 96:  format = ISL_FORMAT_R32G32B32_UINT;    break;
7607ec681f3Smrg         case 128: format = ISL_FORMAT_R32G32B32A32_UINT; break;
7617ec681f3Smrg         default:
7627ec681f3Smrg            unreachable("Unknown format bpb");
7637ec681f3Smrg         }
7647ec681f3Smrg
7657ec681f3Smrg         /* No aux surfaces for non-renderable surfaces */
7667ec681f3Smrg         assert(res->aux.usage == ISL_AUX_USAGE_NONE);
7677ec681f3Smrg      }
7687ec681f3Smrg
7697ec681f3Smrg      isl_color_value_unpack(&color, format, data);
7707ec681f3Smrg
7717ec681f3Smrg      clear_color(ice, p_res, level, box, true, format,
7727ec681f3Smrg                  ISL_SWIZZLE_IDENTITY, color);
7737ec681f3Smrg   }
7747ec681f3Smrg}
7757ec681f3Smrg
7767ec681f3Smrg/**
7777ec681f3Smrg * The pipe->clear_render_target() driver hook.
7787ec681f3Smrg *
7797ec681f3Smrg * This clears the given render target surface.
7807ec681f3Smrg */
7817ec681f3Smrgstatic void
7827ec681f3Smrgcrocus_clear_render_target(struct pipe_context *ctx,
7837ec681f3Smrg                           struct pipe_surface *psurf,
7847ec681f3Smrg                           const union pipe_color_union *p_color,
7857ec681f3Smrg                           unsigned dst_x, unsigned dst_y,
7867ec681f3Smrg                           unsigned width, unsigned height,
7877ec681f3Smrg                           bool render_condition_enabled)
7887ec681f3Smrg{
7897ec681f3Smrg   struct crocus_context *ice = (void *) ctx;
7907ec681f3Smrg   struct crocus_surface *isurf = (void *) psurf;
7917ec681f3Smrg   struct pipe_box box = {
7927ec681f3Smrg      .x = dst_x,
7937ec681f3Smrg      .y = dst_y,
7947ec681f3Smrg      .z = psurf->u.tex.first_layer,
7957ec681f3Smrg      .width = width,
7967ec681f3Smrg      .height = height,
7977ec681f3Smrg      .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
7987ec681f3Smrg   };
7997ec681f3Smrg
8007ec681f3Smrg   /* pipe_color_union and isl_color_value are interchangeable */
8017ec681f3Smrg   union isl_color_value *color = (void *) p_color;
8027ec681f3Smrg
8037ec681f3Smrg   clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
8047ec681f3Smrg               render_condition_enabled,
8057ec681f3Smrg               isurf->view.format, isurf->view.swizzle, *color);
8067ec681f3Smrg}
8077ec681f3Smrg
8087ec681f3Smrg/**
8097ec681f3Smrg * The pipe->clear_depth_stencil() driver hook.
8107ec681f3Smrg *
8117ec681f3Smrg * This clears the given depth/stencil surface.
8127ec681f3Smrg */
8137ec681f3Smrgstatic void
8147ec681f3Smrgcrocus_clear_depth_stencil(struct pipe_context *ctx,
8157ec681f3Smrg                           struct pipe_surface *psurf,
8167ec681f3Smrg                           unsigned flags,
8177ec681f3Smrg                           double depth,
8187ec681f3Smrg                           unsigned stencil,
8197ec681f3Smrg                           unsigned dst_x, unsigned dst_y,
8207ec681f3Smrg                           unsigned width, unsigned height,
8217ec681f3Smrg                           bool render_condition_enabled)
8227ec681f3Smrg{
8237ec681f3Smrg   return;
8247ec681f3Smrg#if 0
8257ec681f3Smrg   struct crocus_context *ice = (void *) ctx;
8267ec681f3Smrg   struct pipe_box box = {
8277ec681f3Smrg      .x = dst_x,
8287ec681f3Smrg      .y = dst_y,
8297ec681f3Smrg      .z = psurf->u.tex.first_layer,
8307ec681f3Smrg      .width = width,
8317ec681f3Smrg      .height = height,
8327ec681f3Smrg      .depth = psurf->u.tex.last_layer - psurf->u.tex.first_layer + 1
8337ec681f3Smrg   };
8347ec681f3Smrg   uint32_t blit_flags = 0;
8357ec681f3Smrg
8367ec681f3Smrg   assert(util_format_is_depth_or_stencil(psurf->texture->format));
8377ec681f3Smrg
8387ec681f3Smrg   crocus_blitter_begin(ice, CROCUS_SAVE_FRAGMENT_STATE);
8397ec681f3Smrg   util_blitter_clear(ice->blitter, width, height,
8407ec681f3Smrg                      1, flags, NULL, depth, stencil, render_condition_enabled);
8417ec681f3Smrg#if 0
8427ec681f3Smrg   clear_depth_stencil(ice, psurf->texture, psurf->u.tex.level, &box,
8437ec681f3Smrg                       render_condition_enabled,
8447ec681f3Smrg                       flags & PIPE_CLEAR_DEPTH, flags & PIPE_CLEAR_STENCIL,
8457ec681f3Smrg                       depth, stencil);
8467ec681f3Smrg#endif
8477ec681f3Smrg#endif
8487ec681f3Smrg}
8497ec681f3Smrg
8507ec681f3Smrgvoid
8517ec681f3Smrgcrocus_init_clear_functions(struct pipe_context *ctx)
8527ec681f3Smrg{
8537ec681f3Smrg   ctx->clear = crocus_clear;
8547ec681f3Smrg   ctx->clear_texture = crocus_clear_texture;
8557ec681f3Smrg   ctx->clear_render_target = crocus_clear_render_target;
8567ec681f3Smrg   ctx->clear_depth_stencil = crocus_clear_depth_stencil;
8577ec681f3Smrg}
858