LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gem - i915_gem_object_blt.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 272 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 7 0.0 %
Branches: 0 88 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: MIT
       2                 :            : /*
       3                 :            :  * Copyright © 2019 Intel Corporation
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "i915_drv.h"
       7                 :            : #include "gt/intel_context.h"
       8                 :            : #include "gt/intel_engine_pm.h"
       9                 :            : #include "gt/intel_engine_pool.h"
      10                 :            : #include "gt/intel_gt.h"
      11                 :            : #include "gt/intel_ring.h"
      12                 :            : #include "i915_gem_clflush.h"
      13                 :            : #include "i915_gem_object_blt.h"
      14                 :            : 
      15                 :          0 : struct i915_vma *intel_emit_vma_fill_blt(struct intel_context *ce,
      16                 :            :                                          struct i915_vma *vma,
      17                 :            :                                          u32 value)
      18                 :            : {
      19                 :          0 :         struct drm_i915_private *i915 = ce->vm->i915;
      20                 :          0 :         const u32 block_size = SZ_8M; /* ~1ms at 8GiB/s preemption delay */
      21                 :          0 :         struct intel_engine_pool_node *pool;
      22                 :          0 :         struct i915_vma *batch;
      23                 :          0 :         u64 offset;
      24                 :          0 :         u64 count;
      25                 :          0 :         u64 rem;
      26                 :          0 :         u32 size;
      27                 :          0 :         u32 *cmd;
      28                 :          0 :         int err;
      29                 :            : 
      30                 :          0 :         GEM_BUG_ON(intel_engine_is_virtual(ce->engine));
      31                 :          0 :         intel_engine_pm_get(ce->engine);
      32                 :            : 
      33                 :          0 :         count = div_u64(round_up(vma->size, block_size), block_size);
      34                 :          0 :         size = (1 + 8 * count) * sizeof(u32);
      35                 :          0 :         size = round_up(size, PAGE_SIZE);
      36                 :          0 :         pool = intel_engine_get_pool(ce->engine, size);
      37         [ #  # ]:          0 :         if (IS_ERR(pool)) {
      38                 :          0 :                 err = PTR_ERR(pool);
      39                 :          0 :                 goto out_pm;
      40                 :            :         }
      41                 :            : 
      42                 :          0 :         cmd = i915_gem_object_pin_map(pool->obj, I915_MAP_WC);
      43         [ #  # ]:          0 :         if (IS_ERR(cmd)) {
      44                 :          0 :                 err = PTR_ERR(cmd);
      45                 :          0 :                 goto out_put;
      46                 :            :         }
      47                 :            : 
      48                 :          0 :         rem = vma->size;
      49                 :          0 :         offset = vma->node.start;
      50                 :            : 
      51                 :          0 :         do {
      52                 :          0 :                 u32 size = min_t(u64, rem, block_size);
      53                 :            : 
      54                 :          0 :                 GEM_BUG_ON(size >> PAGE_SHIFT > S16_MAX);
      55                 :            : 
      56         [ #  # ]:          0 :                 if (INTEL_GEN(i915) >= 8) {
      57                 :          0 :                         *cmd++ = XY_COLOR_BLT_CMD | BLT_WRITE_RGBA | (7 - 2);
      58                 :          0 :                         *cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
      59                 :          0 :                         *cmd++ = 0;
      60                 :          0 :                         *cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
      61                 :          0 :                         *cmd++ = lower_32_bits(offset);
      62                 :          0 :                         *cmd++ = upper_32_bits(offset);
      63                 :          0 :                         *cmd++ = value;
      64                 :            :                 } else {
      65                 :          0 :                         *cmd++ = XY_COLOR_BLT_CMD | BLT_WRITE_RGBA | (6 - 2);
      66                 :          0 :                         *cmd++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | PAGE_SIZE;
      67                 :          0 :                         *cmd++ = 0;
      68                 :          0 :                         *cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
      69                 :          0 :                         *cmd++ = offset;
      70                 :          0 :                         *cmd++ = value;
      71                 :            :                 }
      72                 :            : 
      73                 :            :                 /* Allow ourselves to be preempted in between blocks. */
      74                 :          0 :                 *cmd++ = MI_ARB_CHECK;
      75                 :            : 
      76                 :          0 :                 offset += size;
      77                 :          0 :                 rem -= size;
      78         [ #  # ]:          0 :         } while (rem);
      79                 :            : 
      80                 :          0 :         *cmd = MI_BATCH_BUFFER_END;
      81                 :          0 :         intel_gt_chipset_flush(ce->vm->gt);
      82                 :            : 
      83                 :          0 :         i915_gem_object_unpin_map(pool->obj);
      84                 :            : 
      85                 :          0 :         batch = i915_vma_instance(pool->obj, ce->vm, NULL);
      86         [ #  # ]:          0 :         if (IS_ERR(batch)) {
      87                 :          0 :                 err = PTR_ERR(batch);
      88                 :          0 :                 goto out_put;
      89                 :            :         }
      90                 :            : 
      91                 :          0 :         err = i915_vma_pin(batch, 0, 0, PIN_USER);
      92         [ #  # ]:          0 :         if (unlikely(err))
      93                 :          0 :                 goto out_put;
      94                 :            : 
      95                 :          0 :         batch->private = pool;
      96                 :          0 :         return batch;
      97                 :            : 
      98                 :          0 : out_put:
      99                 :          0 :         intel_engine_pool_put(pool);
     100                 :          0 : out_pm:
     101                 :          0 :         intel_engine_pm_put(ce->engine);
     102                 :          0 :         return ERR_PTR(err);
     103                 :            : }
     104                 :            : 
     105                 :          0 : int intel_emit_vma_mark_active(struct i915_vma *vma, struct i915_request *rq)
     106                 :            : {
     107                 :          0 :         int err;
     108                 :            : 
     109                 :          0 :         i915_vma_lock(vma);
     110                 :          0 :         err = i915_request_await_object(rq, vma->obj, false);
     111         [ #  # ]:          0 :         if (err == 0)
     112                 :          0 :                 err = i915_vma_move_to_active(vma, rq, 0);
     113                 :          0 :         i915_vma_unlock(vma);
     114         [ #  # ]:          0 :         if (unlikely(err))
     115                 :            :                 return err;
     116                 :            : 
     117                 :          0 :         return intel_engine_pool_mark_active(vma->private, rq);
     118                 :            : }
     119                 :            : 
     120                 :          0 : void intel_emit_vma_release(struct intel_context *ce, struct i915_vma *vma)
     121                 :            : {
     122                 :          0 :         i915_vma_unpin(vma);
     123                 :          0 :         intel_engine_pool_put(vma->private);
     124                 :          0 :         intel_engine_pm_put(ce->engine);
     125                 :          0 : }
     126                 :            : 
     127                 :          0 : int i915_gem_object_fill_blt(struct drm_i915_gem_object *obj,
     128                 :            :                              struct intel_context *ce,
     129                 :            :                              u32 value)
     130                 :            : {
     131                 :          0 :         struct i915_request *rq;
     132                 :          0 :         struct i915_vma *batch;
     133                 :          0 :         struct i915_vma *vma;
     134                 :          0 :         int err;
     135                 :            : 
     136                 :          0 :         vma = i915_vma_instance(obj, ce->vm, NULL);
     137         [ #  # ]:          0 :         if (IS_ERR(vma))
     138                 :          0 :                 return PTR_ERR(vma);
     139                 :            : 
     140                 :          0 :         err = i915_vma_pin(vma, 0, 0, PIN_USER);
     141         [ #  # ]:          0 :         if (unlikely(err))
     142                 :            :                 return err;
     143                 :            : 
     144         [ #  # ]:          0 :         if (obj->cache_dirty & ~obj->cache_coherent) {
     145                 :          0 :                 i915_gem_object_lock(obj);
     146                 :          0 :                 i915_gem_clflush_object(obj, 0);
     147                 :          0 :                 i915_gem_object_unlock(obj);
     148                 :            :         }
     149                 :            : 
     150                 :          0 :         batch = intel_emit_vma_fill_blt(ce, vma, value);
     151         [ #  # ]:          0 :         if (IS_ERR(batch)) {
     152                 :          0 :                 err = PTR_ERR(batch);
     153                 :          0 :                 goto out_unpin;
     154                 :            :         }
     155                 :            : 
     156                 :          0 :         rq = intel_context_create_request(ce);
     157         [ #  # ]:          0 :         if (IS_ERR(rq)) {
     158                 :          0 :                 err = PTR_ERR(rq);
     159                 :          0 :                 goto out_batch;
     160                 :            :         }
     161                 :            : 
     162                 :          0 :         err = intel_emit_vma_mark_active(batch, rq);
     163         [ #  # ]:          0 :         if (unlikely(err))
     164                 :          0 :                 goto out_request;
     165                 :            : 
     166                 :          0 :         err = i915_request_await_object(rq, obj, true);
     167         [ #  # ]:          0 :         if (unlikely(err))
     168                 :          0 :                 goto out_request;
     169                 :            : 
     170         [ #  # ]:          0 :         if (ce->engine->emit_init_breadcrumb) {
     171                 :          0 :                 err = ce->engine->emit_init_breadcrumb(rq);
     172         [ #  # ]:          0 :                 if (unlikely(err))
     173                 :          0 :                         goto out_request;
     174                 :            :         }
     175                 :            : 
     176                 :          0 :         i915_vma_lock(vma);
     177                 :          0 :         err = i915_request_await_object(rq, vma->obj, true);
     178         [ #  # ]:          0 :         if (err == 0)
     179                 :          0 :                 err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
     180                 :          0 :         i915_vma_unlock(vma);
     181         [ #  # ]:          0 :         if (unlikely(err))
     182                 :          0 :                 goto out_request;
     183                 :            : 
     184                 :          0 :         err = ce->engine->emit_bb_start(rq,
     185                 :          0 :                                         batch->node.start, batch->node.size,
     186                 :            :                                         0);
     187                 :          0 : out_request:
     188         [ #  # ]:          0 :         if (unlikely(err))
     189                 :          0 :                 i915_request_skip(rq, err);
     190                 :            : 
     191                 :          0 :         i915_request_add(rq);
     192                 :          0 : out_batch:
     193                 :          0 :         intel_emit_vma_release(ce, batch);
     194                 :          0 : out_unpin:
     195                 :          0 :         i915_vma_unpin(vma);
     196                 :          0 :         return err;
     197                 :            : }
     198                 :            : 
     199                 :          0 : struct i915_vma *intel_emit_vma_copy_blt(struct intel_context *ce,
     200                 :            :                                          struct i915_vma *src,
     201                 :            :                                          struct i915_vma *dst)
     202                 :            : {
     203                 :          0 :         struct drm_i915_private *i915 = ce->vm->i915;
     204                 :          0 :         const u32 block_size = SZ_8M; /* ~1ms at 8GiB/s preemption delay */
     205                 :          0 :         struct intel_engine_pool_node *pool;
     206                 :          0 :         struct i915_vma *batch;
     207                 :          0 :         u64 src_offset, dst_offset;
     208                 :          0 :         u64 count, rem;
     209                 :          0 :         u32 size, *cmd;
     210                 :          0 :         int err;
     211                 :            : 
     212                 :          0 :         GEM_BUG_ON(src->size != dst->size);
     213                 :            : 
     214                 :          0 :         GEM_BUG_ON(intel_engine_is_virtual(ce->engine));
     215                 :          0 :         intel_engine_pm_get(ce->engine);
     216                 :            : 
     217                 :          0 :         count = div_u64(round_up(dst->size, block_size), block_size);
     218                 :          0 :         size = (1 + 11 * count) * sizeof(u32);
     219                 :          0 :         size = round_up(size, PAGE_SIZE);
     220                 :          0 :         pool = intel_engine_get_pool(ce->engine, size);
     221         [ #  # ]:          0 :         if (IS_ERR(pool)) {
     222                 :          0 :                 err = PTR_ERR(pool);
     223                 :          0 :                 goto out_pm;
     224                 :            :         }
     225                 :            : 
     226                 :          0 :         cmd = i915_gem_object_pin_map(pool->obj, I915_MAP_WC);
     227         [ #  # ]:          0 :         if (IS_ERR(cmd)) {
     228                 :          0 :                 err = PTR_ERR(cmd);
     229                 :          0 :                 goto out_put;
     230                 :            :         }
     231                 :            : 
     232                 :          0 :         rem = src->size;
     233                 :          0 :         src_offset = src->node.start;
     234                 :          0 :         dst_offset = dst->node.start;
     235                 :            : 
     236                 :          0 :         do {
     237                 :          0 :                 size = min_t(u64, rem, block_size);
     238                 :          0 :                 GEM_BUG_ON(size >> PAGE_SHIFT > S16_MAX);
     239                 :            : 
     240         [ #  # ]:          0 :                 if (INTEL_GEN(i915) >= 9) {
     241                 :          0 :                         *cmd++ = GEN9_XY_FAST_COPY_BLT_CMD | (10 - 2);
     242                 :          0 :                         *cmd++ = BLT_DEPTH_32 | PAGE_SIZE;
     243                 :          0 :                         *cmd++ = 0;
     244                 :          0 :                         *cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
     245                 :          0 :                         *cmd++ = lower_32_bits(dst_offset);
     246                 :          0 :                         *cmd++ = upper_32_bits(dst_offset);
     247                 :          0 :                         *cmd++ = 0;
     248                 :          0 :                         *cmd++ = PAGE_SIZE;
     249                 :          0 :                         *cmd++ = lower_32_bits(src_offset);
     250                 :          0 :                         *cmd++ = upper_32_bits(src_offset);
     251         [ #  # ]:          0 :                 } else if (INTEL_GEN(i915) >= 8) {
     252                 :          0 :                         *cmd++ = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (10 - 2);
     253                 :          0 :                         *cmd++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
     254                 :          0 :                         *cmd++ = 0;
     255                 :          0 :                         *cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE / 4;
     256                 :          0 :                         *cmd++ = lower_32_bits(dst_offset);
     257                 :          0 :                         *cmd++ = upper_32_bits(dst_offset);
     258                 :          0 :                         *cmd++ = 0;
     259                 :          0 :                         *cmd++ = PAGE_SIZE;
     260                 :          0 :                         *cmd++ = lower_32_bits(src_offset);
     261                 :          0 :                         *cmd++ = upper_32_bits(src_offset);
     262                 :            :                 } else {
     263                 :          0 :                         *cmd++ = SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (6 - 2);
     264                 :          0 :                         *cmd++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | PAGE_SIZE;
     265                 :          0 :                         *cmd++ = size >> PAGE_SHIFT << 16 | PAGE_SIZE;
     266                 :          0 :                         *cmd++ = dst_offset;
     267                 :          0 :                         *cmd++ = PAGE_SIZE;
     268                 :          0 :                         *cmd++ = src_offset;
     269                 :            :                 }
     270                 :            : 
     271                 :            :                 /* Allow ourselves to be preempted in between blocks. */
     272                 :          0 :                 *cmd++ = MI_ARB_CHECK;
     273                 :            : 
     274                 :          0 :                 src_offset += size;
     275                 :          0 :                 dst_offset += size;
     276                 :          0 :                 rem -= size;
     277         [ #  # ]:          0 :         } while (rem);
     278                 :            : 
     279                 :          0 :         *cmd = MI_BATCH_BUFFER_END;
     280                 :          0 :         intel_gt_chipset_flush(ce->vm->gt);
     281                 :            : 
     282                 :          0 :         i915_gem_object_unpin_map(pool->obj);
     283                 :            : 
     284                 :          0 :         batch = i915_vma_instance(pool->obj, ce->vm, NULL);
     285         [ #  # ]:          0 :         if (IS_ERR(batch)) {
     286                 :          0 :                 err = PTR_ERR(batch);
     287                 :          0 :                 goto out_put;
     288                 :            :         }
     289                 :            : 
     290                 :          0 :         err = i915_vma_pin(batch, 0, 0, PIN_USER);
     291         [ #  # ]:          0 :         if (unlikely(err))
     292                 :          0 :                 goto out_put;
     293                 :            : 
     294                 :          0 :         batch->private = pool;
     295                 :          0 :         return batch;
     296                 :            : 
     297                 :          0 : out_put:
     298                 :          0 :         intel_engine_pool_put(pool);
     299                 :          0 : out_pm:
     300                 :          0 :         intel_engine_pm_put(ce->engine);
     301                 :          0 :         return ERR_PTR(err);
     302                 :            : }
     303                 :            : 
     304                 :          0 : static int move_to_gpu(struct i915_vma *vma, struct i915_request *rq, bool write)
     305                 :            : {
     306                 :          0 :         struct drm_i915_gem_object *obj = vma->obj;
     307                 :            : 
     308         [ #  # ]:          0 :         if (obj->cache_dirty & ~obj->cache_coherent)
     309                 :          0 :                 i915_gem_clflush_object(obj, 0);
     310                 :            : 
     311                 :          0 :         return i915_request_await_object(rq, obj, write);
     312                 :            : }
     313                 :            : 
     314                 :          0 : int i915_gem_object_copy_blt(struct drm_i915_gem_object *src,
     315                 :            :                              struct drm_i915_gem_object *dst,
     316                 :            :                              struct intel_context *ce)
     317                 :            : {
     318                 :          0 :         struct drm_gem_object *objs[] = { &src->base, &dst->base };
     319                 :          0 :         struct i915_address_space *vm = ce->vm;
     320                 :          0 :         struct i915_vma *vma[2], *batch;
     321                 :          0 :         struct ww_acquire_ctx acquire;
     322                 :          0 :         struct i915_request *rq;
     323                 :          0 :         int err, i;
     324                 :            : 
     325                 :          0 :         vma[0] = i915_vma_instance(src, vm, NULL);
     326         [ #  # ]:          0 :         if (IS_ERR(vma[0]))
     327                 :          0 :                 return PTR_ERR(vma[0]);
     328                 :            : 
     329                 :          0 :         err = i915_vma_pin(vma[0], 0, 0, PIN_USER);
     330         [ #  # ]:          0 :         if (unlikely(err))
     331                 :            :                 return err;
     332                 :            : 
     333                 :          0 :         vma[1] = i915_vma_instance(dst, vm, NULL);
     334         [ #  # ]:          0 :         if (IS_ERR(vma[1]))
     335                 :          0 :                 goto out_unpin_src;
     336                 :            : 
     337                 :          0 :         err = i915_vma_pin(vma[1], 0, 0, PIN_USER);
     338         [ #  # ]:          0 :         if (unlikely(err))
     339                 :          0 :                 goto out_unpin_src;
     340                 :            : 
     341                 :          0 :         batch = intel_emit_vma_copy_blt(ce, vma[0], vma[1]);
     342         [ #  # ]:          0 :         if (IS_ERR(batch)) {
     343                 :          0 :                 err = PTR_ERR(batch);
     344                 :          0 :                 goto out_unpin_dst;
     345                 :            :         }
     346                 :            : 
     347                 :          0 :         rq = intel_context_create_request(ce);
     348         [ #  # ]:          0 :         if (IS_ERR(rq)) {
     349                 :          0 :                 err = PTR_ERR(rq);
     350                 :          0 :                 goto out_batch;
     351                 :            :         }
     352                 :            : 
     353                 :          0 :         err = intel_emit_vma_mark_active(batch, rq);
     354         [ #  # ]:          0 :         if (unlikely(err))
     355                 :          0 :                 goto out_request;
     356                 :            : 
     357                 :          0 :         err = drm_gem_lock_reservations(objs, ARRAY_SIZE(objs), &acquire);
     358         [ #  # ]:          0 :         if (unlikely(err))
     359                 :          0 :                 goto out_request;
     360                 :            : 
     361         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(vma); i++) {
     362                 :          0 :                 err = move_to_gpu(vma[i], rq, i);
     363         [ #  # ]:          0 :                 if (unlikely(err))
     364                 :          0 :                         goto out_unlock;
     365                 :            :         }
     366                 :            : 
     367         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(vma); i++) {
     368         [ #  # ]:          0 :                 unsigned int flags = i ? EXEC_OBJECT_WRITE : 0;
     369                 :            : 
     370                 :          0 :                 err = i915_vma_move_to_active(vma[i], rq, flags);
     371         [ #  # ]:          0 :                 if (unlikely(err))
     372                 :          0 :                         goto out_unlock;
     373                 :            :         }
     374                 :            : 
     375         [ #  # ]:          0 :         if (rq->engine->emit_init_breadcrumb) {
     376                 :          0 :                 err = rq->engine->emit_init_breadcrumb(rq);
     377         [ #  # ]:          0 :                 if (unlikely(err))
     378                 :          0 :                         goto out_unlock;
     379                 :            :         }
     380                 :            : 
     381                 :          0 :         err = rq->engine->emit_bb_start(rq,
     382                 :          0 :                                         batch->node.start, batch->node.size,
     383                 :            :                                         0);
     384                 :          0 : out_unlock:
     385                 :          0 :         drm_gem_unlock_reservations(objs, ARRAY_SIZE(objs), &acquire);
     386                 :          0 : out_request:
     387         [ #  # ]:          0 :         if (unlikely(err))
     388                 :          0 :                 i915_request_skip(rq, err);
     389                 :            : 
     390                 :          0 :         i915_request_add(rq);
     391                 :          0 : out_batch:
     392                 :          0 :         intel_emit_vma_release(ce, batch);
     393                 :          0 : out_unpin_dst:
     394                 :          0 :         i915_vma_unpin(vma[1]);
     395                 :          0 : out_unpin_src:
     396                 :          0 :         i915_vma_unpin(vma[0]);
     397                 :          0 :         return err;
     398                 :            : }
     399                 :            : 
     400                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
     401                 :            : #include "selftests/i915_gem_object_blt.c"
     402                 :            : #endif

Generated by: LCOV version 1.14