Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  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.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Jerome Glisse
  25.  */
  26. #include "r600_pipe.h"
  27. #include "r600d.h"
  28. #include "util/u_memory.h"
  29. #include <errno.h>
  30. #include <unistd.h>
  31.  
  32.  
  33. void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
  34.                         boolean count_draw_in)
  35. {
  36.  
  37.         if (!ctx->b.ws->cs_memory_below_limit(ctx->b.rings.gfx.cs, ctx->b.vram, ctx->b.gtt)) {
  38.                 ctx->b.gtt = 0;
  39.                 ctx->b.vram = 0;
  40.                 ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
  41.                 return;
  42.         }
  43.         /* all will be accounted once relocation are emited */
  44.         ctx->b.gtt = 0;
  45.         ctx->b.vram = 0;
  46.  
  47.         /* The number of dwords we already used in the CS so far. */
  48.         num_dw += ctx->b.rings.gfx.cs->cdw;
  49.  
  50.         if (count_draw_in) {
  51.                 unsigned i;
  52.  
  53.                 /* The number of dwords all the dirty states would take. */
  54.                 for (i = 0; i < R600_NUM_ATOMS; i++) {
  55.                         if (ctx->atoms[i] && ctx->atoms[i]->dirty) {
  56.                                 num_dw += ctx->atoms[i]->num_dw;
  57.                                 if (ctx->screen->b.trace_bo) {
  58.                                         num_dw += R600_TRACE_CS_DWORDS;
  59.                                 }
  60.                         }
  61.                 }
  62.  
  63.                 /* The upper-bound of how much space a draw command would take. */
  64.                 num_dw += R600_MAX_FLUSH_CS_DWORDS + R600_MAX_DRAW_CS_DWORDS;
  65.                 if (ctx->screen->b.trace_bo) {
  66.                         num_dw += R600_TRACE_CS_DWORDS;
  67.                 }
  68.         }
  69.  
  70.         /* Count in queries_suspend. */
  71.         num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
  72.  
  73.         /* Count in streamout_end at the end of CS. */
  74.         if (ctx->b.streamout.begin_emitted) {
  75.                 num_dw += ctx->b.streamout.num_dw_for_end;
  76.         }
  77.  
  78.         /* Count in render_condition(NULL) at the end of CS. */
  79.         if (ctx->b.predicate_drawing) {
  80.                 num_dw += 3;
  81.         }
  82.  
  83.         /* SX_MISC */
  84.         if (ctx->b.chip_class == R600) {
  85.                 num_dw += 3;
  86.         }
  87.  
  88.         /* Count in framebuffer cache flushes at the end of CS. */
  89.         num_dw += R600_MAX_FLUSH_CS_DWORDS;
  90.  
  91.         /* The fence at the end of CS. */
  92.         num_dw += 10;
  93.  
  94.         /* Flush if there's not enough space. */
  95.         if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
  96.                 ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
  97.         }
  98. }
  99.  
  100. void r600_flush_emit(struct r600_context *rctx)
  101. {
  102.         struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
  103.         unsigned cp_coher_cntl = 0;
  104.         unsigned wait_until = 0;
  105.  
  106.         if (!rctx->b.flags) {
  107.                 return;
  108.         }
  109.  
  110.         if (rctx->b.flags & R600_CONTEXT_WAIT_3D_IDLE) {
  111.                 wait_until |= S_008040_WAIT_3D_IDLE(1);
  112.         }
  113.         if (rctx->b.flags & R600_CONTEXT_WAIT_CP_DMA_IDLE) {
  114.                 wait_until |= S_008040_WAIT_CP_DMA_IDLE(1);
  115.         }
  116.  
  117.         if (wait_until) {
  118.                 /* Use of WAIT_UNTIL is deprecated on Cayman+ */
  119.                 if (rctx->b.family >= CHIP_CAYMAN) {
  120.                         /* emit a PS partial flush on Cayman/TN */
  121.                         rctx->b.flags |= R600_CONTEXT_PS_PARTIAL_FLUSH;
  122.                 }
  123.         }
  124.  
  125.         if (rctx->b.flags & R600_CONTEXT_PS_PARTIAL_FLUSH) {
  126.                 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
  127.                 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
  128.         }
  129.  
  130.         if (rctx->b.chip_class >= R700 &&
  131.             (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_CB_META)) {
  132.                 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
  133.                 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_FLUSH_AND_INV_CB_META) | EVENT_INDEX(0);
  134.         }
  135.  
  136.         if (rctx->b.chip_class >= R700 &&
  137.             (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_DB_META)) {
  138.                 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
  139.                 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_FLUSH_AND_INV_DB_META) | EVENT_INDEX(0);
  140.  
  141.                 /* Set FULL_CACHE_ENA for DB META flushes on r7xx and later.
  142.                  *
  143.                  * This hack predates use of FLUSH_AND_INV_DB_META, so it's
  144.                  * unclear whether it's still needed or even whether it has
  145.                  * any effect.
  146.                  */
  147.                 cp_coher_cntl |= S_0085F0_FULL_CACHE_ENA(1);
  148.         }
  149.  
  150.         if (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV ||
  151.             (rctx->b.chip_class == R600 && rctx->b.flags & R600_CONTEXT_STREAMOUT_FLUSH)) {
  152.                 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
  153.                 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
  154.         }
  155.  
  156.         if (rctx->b.flags & R600_CONTEXT_INV_CONST_CACHE) {
  157.                 /* Direct constant addressing uses the shader cache.
  158.                  * Indirect contant addressing uses the vertex cache. */
  159.                 cp_coher_cntl |= S_0085F0_SH_ACTION_ENA(1) |
  160.                                  (rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1)
  161.                                                          : S_0085F0_TC_ACTION_ENA(1));
  162.         }
  163.         if (rctx->b.flags & R600_CONTEXT_INV_VERTEX_CACHE) {
  164.                 cp_coher_cntl |= rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1)
  165.                                                         : S_0085F0_TC_ACTION_ENA(1);
  166.         }
  167.         if (rctx->b.flags & R600_CONTEXT_INV_TEX_CACHE) {
  168.                 /* Textures use the texture cache.
  169.                  * Texture buffer objects use the vertex cache. */
  170.                 cp_coher_cntl |= S_0085F0_TC_ACTION_ENA(1) |
  171.                                  (rctx->has_vertex_cache ? S_0085F0_VC_ACTION_ENA(1) : 0);
  172.         }
  173.  
  174.         /* Don't use the DB CP COHER logic on r6xx.
  175.          * There are hw bugs.
  176.          */
  177.         if (rctx->b.chip_class >= R700 &&
  178.             (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_DB)) {
  179.                 cp_coher_cntl |= S_0085F0_DB_ACTION_ENA(1) |
  180.                                 S_0085F0_DB_DEST_BASE_ENA(1) |
  181.                                 S_0085F0_SMX_ACTION_ENA(1);
  182.         }
  183.  
  184.         /* Don't use the CB CP COHER logic on r6xx.
  185.          * There are hw bugs.
  186.          */
  187.         if (rctx->b.chip_class >= R700 &&
  188.             (rctx->b.flags & R600_CONTEXT_FLUSH_AND_INV_CB)) {
  189.                 cp_coher_cntl |= S_0085F0_CB_ACTION_ENA(1) |
  190.                                 S_0085F0_CB0_DEST_BASE_ENA(1) |
  191.                                 S_0085F0_CB1_DEST_BASE_ENA(1) |
  192.                                 S_0085F0_CB2_DEST_BASE_ENA(1) |
  193.                                 S_0085F0_CB3_DEST_BASE_ENA(1) |
  194.                                 S_0085F0_CB4_DEST_BASE_ENA(1) |
  195.                                 S_0085F0_CB5_DEST_BASE_ENA(1) |
  196.                                 S_0085F0_CB6_DEST_BASE_ENA(1) |
  197.                                 S_0085F0_CB7_DEST_BASE_ENA(1) |
  198.                                 S_0085F0_SMX_ACTION_ENA(1);
  199.                 if (rctx->b.chip_class >= EVERGREEN)
  200.                         cp_coher_cntl |= S_0085F0_CB8_DEST_BASE_ENA(1) |
  201.                                         S_0085F0_CB9_DEST_BASE_ENA(1) |
  202.                                         S_0085F0_CB10_DEST_BASE_ENA(1) |
  203.                                         S_0085F0_CB11_DEST_BASE_ENA(1);
  204.         }
  205.  
  206.         if (rctx->b.chip_class >= R700 &&
  207.             rctx->b.flags & R600_CONTEXT_STREAMOUT_FLUSH) {
  208.                 cp_coher_cntl |= S_0085F0_SO0_DEST_BASE_ENA(1) |
  209.                                 S_0085F0_SO1_DEST_BASE_ENA(1) |
  210.                                 S_0085F0_SO2_DEST_BASE_ENA(1) |
  211.                                 S_0085F0_SO3_DEST_BASE_ENA(1) |
  212.                                 S_0085F0_SMX_ACTION_ENA(1);
  213.         }
  214.  
  215.         /* Workaround for buggy flushing on some R6xx chipsets. */
  216.         if ((rctx->b.flags & (R600_CONTEXT_FLUSH_AND_INV |
  217.                               R600_CONTEXT_STREAMOUT_FLUSH)) &&
  218.             (rctx->b.family == CHIP_RV670 ||
  219.              rctx->b.family == CHIP_RS780 ||
  220.              rctx->b.family == CHIP_RS880)) {
  221.                 cp_coher_cntl |=  S_0085F0_CB1_DEST_BASE_ENA(1) |
  222.                                   S_0085F0_DEST_BASE_0_ENA(1);
  223.         }
  224.  
  225.         if (cp_coher_cntl) {
  226.                 cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
  227.                 cs->buf[cs->cdw++] = cp_coher_cntl;   /* CP_COHER_CNTL */
  228.                 cs->buf[cs->cdw++] = 0xffffffff;      /* CP_COHER_SIZE */
  229.                 cs->buf[cs->cdw++] = 0;               /* CP_COHER_BASE */
  230.                 cs->buf[cs->cdw++] = 0x0000000A;      /* POLL_INTERVAL */
  231.         }
  232.  
  233.         if (wait_until) {
  234.                 /* Use of WAIT_UNTIL is deprecated on Cayman+ */
  235.                 if (rctx->b.family < CHIP_CAYMAN) {
  236.                         /* wait for things to settle */
  237.                         r600_write_config_reg(cs, R_008040_WAIT_UNTIL, wait_until);
  238.                 }
  239.         }
  240.  
  241.         /* everything is properly flushed */
  242.         rctx->b.flags = 0;
  243. }
  244.  
  245. void r600_context_gfx_flush(void *context, unsigned flags,
  246.                             struct pipe_fence_handle **fence)
  247. {
  248.         struct r600_context *ctx = context;
  249.         struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
  250.  
  251.         if (cs->cdw == ctx->b.initial_gfx_cs_size && !fence)
  252.                 return;
  253.  
  254.         ctx->b.rings.gfx.flushing = true;
  255.  
  256.         r600_preflush_suspend_features(&ctx->b);
  257.  
  258.         /* flush the framebuffer cache */
  259.         ctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV |
  260.                       R600_CONTEXT_FLUSH_AND_INV_CB |
  261.                       R600_CONTEXT_FLUSH_AND_INV_DB |
  262.                       R600_CONTEXT_FLUSH_AND_INV_CB_META |
  263.                       R600_CONTEXT_FLUSH_AND_INV_DB_META |
  264.                       R600_CONTEXT_WAIT_3D_IDLE |
  265.                       R600_CONTEXT_WAIT_CP_DMA_IDLE;
  266.  
  267.         r600_flush_emit(ctx);
  268.  
  269.         /* old kernels and userspace don't set SX_MISC, so we must reset it to 0 here */
  270.         if (ctx->b.chip_class == R600) {
  271.                 r600_write_context_reg(cs, R_028350_SX_MISC, 0);
  272.         }
  273.  
  274.         /* force to keep tiling flags */
  275.         if (ctx->keep_tiling_flags) {
  276.                 flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
  277.         }
  278.  
  279.         /* Flush the CS. */
  280.         ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
  281.         ctx->b.rings.gfx.flushing = false;
  282.  
  283.         r600_begin_new_cs(ctx);
  284. }
  285.  
  286. void r600_begin_new_cs(struct r600_context *ctx)
  287. {
  288.         unsigned shader;
  289.         int i;
  290.         ctx->b.flags = 0;
  291.         ctx->b.gtt = 0;
  292.         ctx->b.vram = 0;
  293.  
  294.         /* Begin a new CS. */
  295.         r600_emit_command_buffer(ctx->b.rings.gfx.cs, &ctx->start_cs_cmd);
  296.  
  297.         /* Re-emit states. */
  298.         ctx->alphatest_state.atom.dirty = true;
  299.         ctx->blend_color.atom.dirty = true;
  300.         ctx->cb_misc_state.atom.dirty = true;
  301.         ctx->clip_misc_state.atom.dirty = true;
  302.         ctx->clip_state.atom.dirty = true;
  303.         ctx->db_misc_state.atom.dirty = true;
  304.         ctx->db_state.atom.dirty = true;
  305.         ctx->framebuffer.atom.dirty = true;
  306.         ctx->pixel_shader.atom.dirty = true;
  307.         ctx->poly_offset_state.atom.dirty = true;
  308.         ctx->vgt_state.atom.dirty = true;
  309.         ctx->sample_mask.atom.dirty = true;
  310.         for (i = 0; i < R600_MAX_VIEWPORTS; i++) {
  311.                 ctx->scissor[i].atom.dirty = true;
  312.                 ctx->viewport[i].atom.dirty = true;
  313.         }
  314.         ctx->config_state.atom.dirty = true;
  315.         ctx->stencil_ref.atom.dirty = true;
  316.         ctx->vertex_fetch_shader.atom.dirty = true;
  317.         ctx->export_shader.atom.dirty = true;
  318.         ctx->shader_stages.atom.dirty = true;
  319.         if (ctx->gs_shader) {
  320.                 ctx->geometry_shader.atom.dirty = true;
  321.                 ctx->gs_rings.atom.dirty = true;
  322.         }
  323.         ctx->vertex_shader.atom.dirty = true;
  324.         ctx->b.streamout.enable_atom.dirty = true;
  325.  
  326.         if (ctx->blend_state.cso)
  327.                 ctx->blend_state.atom.dirty = true;
  328.         if (ctx->dsa_state.cso)
  329.                 ctx->dsa_state.atom.dirty = true;
  330.         if (ctx->rasterizer_state.cso)
  331.                 ctx->rasterizer_state.atom.dirty = true;
  332.  
  333.         if (ctx->b.chip_class <= R700) {
  334.                 ctx->seamless_cube_map.atom.dirty = true;
  335.         }
  336.  
  337.         ctx->vertex_buffer_state.dirty_mask = ctx->vertex_buffer_state.enabled_mask;
  338.         r600_vertex_buffers_dirty(ctx);
  339.  
  340.         /* Re-emit shader resources. */
  341.         for (shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
  342.                 struct r600_constbuf_state *constbuf = &ctx->constbuf_state[shader];
  343.                 struct r600_textures_info *samplers = &ctx->samplers[shader];
  344.  
  345.                 constbuf->dirty_mask = constbuf->enabled_mask;
  346.                 samplers->views.dirty_mask = samplers->views.enabled_mask;
  347.                 samplers->states.dirty_mask = samplers->states.enabled_mask;
  348.  
  349.                 r600_constant_buffers_dirty(ctx, constbuf);
  350.                 r600_sampler_views_dirty(ctx, &samplers->views);
  351.                 r600_sampler_states_dirty(ctx, &samplers->states);
  352.         }
  353.  
  354.         r600_postflush_resume_features(&ctx->b);
  355.  
  356.         /* Re-emit the draw state. */
  357.         ctx->last_primitive_type = -1;
  358.         ctx->last_start_instance = -1;
  359.  
  360.         ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
  361. }
  362.  
  363. /* The max number of bytes to copy per packet. */
  364. #define CP_DMA_MAX_BYTE_COUNT ((1 << 21) - 8)
  365.  
  366. void r600_cp_dma_copy_buffer(struct r600_context *rctx,
  367.                              struct pipe_resource *dst, uint64_t dst_offset,
  368.                              struct pipe_resource *src, uint64_t src_offset,
  369.                              unsigned size)
  370. {
  371.         struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
  372.  
  373.         assert(size);
  374.         assert(rctx->screen->b.has_cp_dma);
  375.  
  376.         /* Mark the buffer range of destination as valid (initialized),
  377.          * so that transfer_map knows it should wait for the GPU when mapping
  378.          * that range. */
  379.         util_range_add(&r600_resource(dst)->valid_buffer_range, dst_offset,
  380.                        dst_offset + size);
  381.  
  382.         dst_offset += r600_resource(dst)->gpu_address;
  383.         src_offset += r600_resource(src)->gpu_address;
  384.  
  385.         /* Flush the caches where the resources are bound. */
  386.         rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE |
  387.                          R600_CONTEXT_INV_VERTEX_CACHE |
  388.                          R600_CONTEXT_INV_TEX_CACHE |
  389.                          R600_CONTEXT_FLUSH_AND_INV |
  390.                          R600_CONTEXT_FLUSH_AND_INV_CB |
  391.                          R600_CONTEXT_FLUSH_AND_INV_DB |
  392.                          R600_CONTEXT_FLUSH_AND_INV_CB_META |
  393.                          R600_CONTEXT_FLUSH_AND_INV_DB_META |
  394.                          R600_CONTEXT_STREAMOUT_FLUSH |
  395.                          R600_CONTEXT_WAIT_3D_IDLE;
  396.  
  397.         /* There are differences between R700 and EG in CP DMA,
  398.          * but we only use the common bits here. */
  399.         while (size) {
  400.                 unsigned sync = 0;
  401.                 unsigned byte_count = MIN2(size, CP_DMA_MAX_BYTE_COUNT);
  402.                 unsigned src_reloc, dst_reloc;
  403.  
  404.                 r600_need_cs_space(rctx, 10 + (rctx->b.flags ? R600_MAX_FLUSH_CS_DWORDS : 0), FALSE);
  405.  
  406.                 /* Flush the caches for the first copy only. */
  407.                 if (rctx->b.flags) {
  408.                         r600_flush_emit(rctx);
  409.                 }
  410.  
  411.                 /* Do the synchronization after the last copy, so that all data is written to memory. */
  412.                 if (size == byte_count) {
  413.                         sync = PKT3_CP_DMA_CP_SYNC;
  414.                 }
  415.  
  416.                 /* This must be done after r600_need_cs_space. */
  417.                 src_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, (struct r600_resource*)src,
  418.                                                   RADEON_USAGE_READ, RADEON_PRIO_MIN);
  419.                 dst_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, (struct r600_resource*)dst,
  420.                                                   RADEON_USAGE_WRITE, RADEON_PRIO_MIN);
  421.  
  422.                 radeon_emit(cs, PKT3(PKT3_CP_DMA, 4, 0));
  423.                 radeon_emit(cs, src_offset);    /* SRC_ADDR_LO [31:0] */
  424.                 radeon_emit(cs, sync | ((src_offset >> 32) & 0xff));            /* CP_SYNC [31] | SRC_ADDR_HI [7:0] */
  425.                 radeon_emit(cs, dst_offset);    /* DST_ADDR_LO [31:0] */
  426.                 radeon_emit(cs, (dst_offset >> 32) & 0xff);             /* DST_ADDR_HI [7:0] */
  427.                 radeon_emit(cs, byte_count);    /* COMMAND [29:22] | BYTE_COUNT [20:0] */
  428.  
  429.                 radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
  430.                 radeon_emit(cs, src_reloc);
  431.                 radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
  432.                 radeon_emit(cs, dst_reloc);
  433.  
  434.                 size -= byte_count;
  435.                 src_offset += byte_count;
  436.                 dst_offset += byte_count;
  437.         }
  438.  
  439.         /* Invalidate the read caches. */
  440.         rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE |
  441.                          R600_CONTEXT_INV_VERTEX_CACHE |
  442.                          R600_CONTEXT_INV_TEX_CACHE;
  443. }
  444.  
  445. void r600_dma_copy_buffer(struct r600_context *rctx,
  446.                           struct pipe_resource *dst,
  447.                           struct pipe_resource *src,
  448.                           uint64_t dst_offset,
  449.                           uint64_t src_offset,
  450.                           uint64_t size)
  451. {
  452.         struct radeon_winsys_cs *cs = rctx->b.rings.dma.cs;
  453.         unsigned i, ncopy, csize;
  454.         struct r600_resource *rdst = (struct r600_resource*)dst;
  455.         struct r600_resource *rsrc = (struct r600_resource*)src;
  456.  
  457.         /* Mark the buffer range of destination as valid (initialized),
  458.          * so that transfer_map knows it should wait for the GPU when mapping
  459.          * that range. */
  460.         util_range_add(&rdst->valid_buffer_range, dst_offset,
  461.                        dst_offset + size);
  462.  
  463.         size >>= 2; /* convert to dwords */
  464.         ncopy = (size / R600_DMA_COPY_MAX_SIZE_DW) + !!(size % R600_DMA_COPY_MAX_SIZE_DW);
  465.  
  466.         r600_need_dma_space(&rctx->b, ncopy * 5);
  467.         for (i = 0; i < ncopy; i++) {
  468.                 csize = size < R600_DMA_COPY_MAX_SIZE_DW ? size : R600_DMA_COPY_MAX_SIZE_DW;
  469.                 /* emit reloc before writing cs so that cs is always in consistent state */
  470.                 r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, rsrc, RADEON_USAGE_READ,
  471.                                       RADEON_PRIO_MIN);
  472.                 r600_context_bo_reloc(&rctx->b, &rctx->b.rings.dma, rdst, RADEON_USAGE_WRITE,
  473.                                       RADEON_PRIO_MIN);
  474.                 cs->buf[cs->cdw++] = DMA_PACKET(DMA_PACKET_COPY, 0, 0, csize);
  475.                 cs->buf[cs->cdw++] = dst_offset & 0xfffffffc;
  476.                 cs->buf[cs->cdw++] = src_offset & 0xfffffffc;
  477.                 cs->buf[cs->cdw++] = (dst_offset >> 32UL) & 0xff;
  478.                 cs->buf[cs->cdw++] = (src_offset >> 32UL) & 0xff;
  479.                 dst_offset += csize << 2;
  480.                 src_offset += csize << 2;
  481.                 size -= csize;
  482.         }
  483. }
  484.