Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2012-2013 LunarG, Inc.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Chia-I Wu <olv@lunarg.com>
  26.  */
  27.  
  28. #include "util/u_surface.h"
  29.  
  30. #include "ilo_blitter.h"
  31. #include "ilo_context.h"
  32. #include "ilo_blit.h"
  33.  
  34. static void
  35. ilo_resource_copy_region(struct pipe_context *pipe,
  36.                          struct pipe_resource *dst,
  37.                          unsigned dst_level,
  38.                          unsigned dstx, unsigned dsty, unsigned dstz,
  39.                          struct pipe_resource *src,
  40.                          unsigned src_level,
  41.                          const struct pipe_box *src_box)
  42. {
  43.    struct ilo_context *ilo = ilo_context(pipe);
  44.  
  45.    if (ilo_blitter_blt_copy_resource(ilo->blitter,
  46.             dst, dst_level, dstx, dsty, dstz,
  47.             src, src_level, src_box))
  48.       return;
  49.  
  50.    if (ilo_blitter_pipe_copy_resource(ilo->blitter,
  51.             dst, dst_level, dstx, dsty, dstz,
  52.             src, src_level, src_box))
  53.       return;
  54.  
  55.    util_resource_copy_region(&ilo->base, dst, dst_level,
  56.          dstx, dsty, dstz, src, src_level, src_box);
  57. }
  58.  
  59. static void
  60. ilo_clear(struct pipe_context *pipe,
  61.           unsigned buffers,
  62.           const union pipe_color_union *color,
  63.           double depth,
  64.           unsigned stencil)
  65. {
  66.    struct ilo_context *ilo = ilo_context(pipe);
  67.    struct ilo_state_vector *vec = &ilo->state_vector;
  68.  
  69.    if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && vec->fb.state.zsbuf) {
  70.       if (ilo_blitter_rectlist_clear_zs(ilo->blitter, vec->fb.state.zsbuf,
  71.                buffers & PIPE_CLEAR_DEPTHSTENCIL, depth, stencil))
  72.          buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
  73.  
  74.       if (!buffers)
  75.          return;
  76.    }
  77.  
  78.    ilo_blitter_pipe_clear_fb(ilo->blitter, buffers, color, depth, stencil);
  79. }
  80.  
  81. static void
  82. ilo_clear_render_target(struct pipe_context *pipe,
  83.                         struct pipe_surface *dst,
  84.                         const union pipe_color_union *color,
  85.                         unsigned dstx, unsigned dsty,
  86.                         unsigned width, unsigned height)
  87. {
  88.    struct ilo_context *ilo = ilo_context(pipe);
  89.  
  90.    if (!width || !height || dstx >= dst->width || dsty >= dst->height)
  91.       return;
  92.  
  93.    if (dstx + width > dst->width)
  94.       width = dst->width - dstx;
  95.    if (dsty + height > dst->height)
  96.       height = dst->height - dsty;
  97.  
  98.    if (ilo_blitter_blt_clear_rt(ilo->blitter,
  99.             dst, color, dstx, dsty, width, height))
  100.       return;
  101.  
  102.    ilo_blitter_pipe_clear_rt(ilo->blitter,
  103.          dst, color, dstx, dsty, width, height);
  104. }
  105.  
  106. static void
  107. ilo_clear_depth_stencil(struct pipe_context *pipe,
  108.                         struct pipe_surface *dst,
  109.                         unsigned clear_flags,
  110.                         double depth,
  111.                         unsigned stencil,
  112.                         unsigned dstx, unsigned dsty,
  113.                         unsigned width, unsigned height)
  114. {
  115.    struct ilo_context *ilo = ilo_context(pipe);
  116.  
  117.    if (!width || !height || dstx >= dst->width || dsty >= dst->height)
  118.       return;
  119.  
  120.    if (dstx + width > dst->width)
  121.       width = dst->width - dstx;
  122.    if (dsty + height > dst->height)
  123.       height = dst->height - dsty;
  124.  
  125.    if (ilo_blitter_blt_clear_zs(ilo->blitter,
  126.             dst, clear_flags, depth, stencil, dstx, dsty, width, height))
  127.       return;
  128.  
  129.    ilo_blitter_pipe_clear_zs(ilo->blitter,
  130.          dst, clear_flags, depth, stencil, dstx, dsty, width, height);
  131. }
  132.  
  133. static void
  134. ilo_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
  135. {
  136.    struct ilo_context *ilo = ilo_context(pipe);
  137.  
  138.    ilo_blitter_pipe_blit(ilo->blitter, info);
  139. }
  140.  
  141. static void
  142. ilo_flush_resource(struct pipe_context *pipe, struct pipe_resource *res)
  143. {
  144.    struct ilo_context *ilo = ilo_context(pipe);
  145.    const unsigned flags = ILO_TEXTURE_CPU_READ |
  146.                           ILO_TEXTURE_BLT_READ |
  147.                           ILO_TEXTURE_RENDER_READ;
  148.  
  149.    ilo_blit_resolve_resource(ilo, res, flags);
  150. }
  151.  
  152. void
  153. ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
  154.                                 struct pipe_resource *res, unsigned level,
  155.                                 unsigned first_slice, unsigned num_slices,
  156.                                 unsigned resolve_flags)
  157. {
  158.    struct ilo_texture *tex = ilo_texture(res);
  159.    const unsigned any_reader =
  160.       ILO_TEXTURE_RENDER_READ |
  161.       ILO_TEXTURE_BLT_READ |
  162.       ILO_TEXTURE_CPU_READ;
  163.    const unsigned other_writers =
  164.       ILO_TEXTURE_BLT_WRITE |
  165.       ILO_TEXTURE_CPU_WRITE;
  166.    unsigned i;
  167.  
  168.    assert(tex->base.target != PIPE_BUFFER &&
  169.           ilo_image_can_enable_aux(&tex->image, level));
  170.  
  171.    if (resolve_flags & ILO_TEXTURE_RENDER_WRITE) {
  172.       /*
  173.        * When ILO_TEXTURE_RENDER_WRITE is set, there can be no reader.  We
  174.        * need to perform a HiZ Buffer Resolve in case the resource was
  175.        * previously written by another writer, unless this is a clear.
  176.        *
  177.        * When slices have different clear values, we perform a Depth Buffer
  178.        * Resolve on all slices not sharing the clear value of the first slice.
  179.        * After resolving, those slices do not use 3DSTATE_CLEAR_PARAMS and can
  180.        * be made to have the same clear value as the first slice does.  This
  181.        * way,
  182.        *
  183.        *  - 3DSTATE_CLEAR_PARAMS can be set to the clear value of any slice
  184.        *  - we will not resolve unnecessarily next time this function is
  185.        *    called
  186.        *
  187.        * Since slice clear value is the value the slice is cleared to when
  188.        * ILO_TEXTURE_CLEAR is set, the bit needs to be unset.
  189.        */
  190.       assert(!(resolve_flags & (other_writers | any_reader)));
  191.  
  192.       if (!(resolve_flags & ILO_TEXTURE_CLEAR)) {
  193.          const uint32_t first_clear_value = ilo_texture_get_slice(tex,
  194.                level, first_slice)->clear_value;
  195.          bool set_clear_value = false;
  196.  
  197.          for (i = 0; i < num_slices; i++) {
  198.             const struct ilo_texture_slice *slice =
  199.                ilo_texture_get_slice(tex, level, first_slice + i);
  200.  
  201.             if (slice->flags & other_writers) {
  202.                ilo_blitter_rectlist_resolve_hiz(ilo->blitter,
  203.                      res, level, first_slice + i);
  204.             } else if (slice->clear_value != first_clear_value &&
  205.                        (slice->flags & ILO_TEXTURE_RENDER_WRITE)) {
  206.                ilo_blitter_rectlist_resolve_z(ilo->blitter,
  207.                      res, level, first_slice + i);
  208.                set_clear_value = true;
  209.             }
  210.          }
  211.  
  212.          if (set_clear_value) {
  213.             /* ILO_TEXTURE_CLEAR will be cleared later */
  214.             ilo_texture_set_slice_clear_value(tex, level,
  215.                   first_slice, num_slices, first_clear_value);
  216.          }
  217.       }
  218.    }
  219.    else if ((resolve_flags & any_reader) ||
  220.             ((resolve_flags & other_writers) &&
  221.              !(resolve_flags & ILO_TEXTURE_CLEAR))) {
  222.       /*
  223.        * When there is at least a reader or writer, we need to perform a
  224.        * Depth Buffer Resolve in case the resource was previously written
  225.        * by ILO_TEXTURE_RENDER_WRITE.
  226.        */
  227.       for (i = 0; i < num_slices; i++) {
  228.          const struct ilo_texture_slice *slice =
  229.             ilo_texture_get_slice(tex, level, first_slice + i);
  230.  
  231.          if (slice->flags & ILO_TEXTURE_RENDER_WRITE) {
  232.             ilo_blitter_rectlist_resolve_z(ilo->blitter,
  233.                   &tex->base, level, first_slice + i);
  234.          }
  235.       }
  236.    }
  237. }
  238.  
  239. /**
  240.  * Initialize blit-related functions.
  241.  */
  242. void
  243. ilo_init_blit_functions(struct ilo_context *ilo)
  244. {
  245.    ilo->base.resource_copy_region = ilo_resource_copy_region;
  246.    ilo->base.blit = ilo_blit;
  247.    ilo->base.flush_resource = ilo_flush_resource;
  248.  
  249.    ilo->base.clear = ilo_clear;
  250.    ilo->base.clear_render_target = ilo_clear_render_target;
  251.    ilo->base.clear_depth_stencil = ilo_clear_depth_stencil;
  252. }
  253.