Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
  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 (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29. #include "freedreno_context.h"
  30. #include "freedreno_draw.h"
  31. #include "freedreno_fence.h"
  32. #include "freedreno_program.h"
  33. #include "freedreno_resource.h"
  34. #include "freedreno_texture.h"
  35. #include "freedreno_state.h"
  36. #include "freedreno_gmem.h"
  37. #include "freedreno_query.h"
  38. #include "freedreno_query_hw.h"
  39. #include "freedreno_util.h"
  40.  
  41. static struct fd_ringbuffer *next_rb(struct fd_context *ctx)
  42. {
  43.         struct fd_ringbuffer *ring;
  44.         uint32_t ts;
  45.  
  46.         /* grab next ringbuffer: */
  47.         ring = ctx->rings[(ctx->rings_idx++) % ARRAY_SIZE(ctx->rings)];
  48.  
  49.         /* wait for new rb to be idle: */
  50.         ts = fd_ringbuffer_timestamp(ring);
  51.         if (ts) {
  52.                 DBG("wait: %u", ts);
  53.                 fd_pipe_wait(ctx->screen->pipe, ts);
  54.         }
  55.  
  56.         fd_ringbuffer_reset(ring);
  57.  
  58.         return ring;
  59. }
  60.  
  61. static void
  62. fd_context_next_rb(struct pipe_context *pctx)
  63. {
  64.         struct fd_context *ctx = fd_context(pctx);
  65.         struct fd_ringbuffer *ring;
  66.  
  67.         fd_ringmarker_del(ctx->draw_start);
  68.         fd_ringmarker_del(ctx->draw_end);
  69.  
  70.         ring = next_rb(ctx);
  71.  
  72.         ctx->draw_start = fd_ringmarker_new(ring);
  73.         ctx->draw_end = fd_ringmarker_new(ring);
  74.  
  75.         fd_ringbuffer_set_parent(ring, NULL);
  76.         ctx->ring = ring;
  77.  
  78.         fd_ringmarker_del(ctx->binning_start);
  79.         fd_ringmarker_del(ctx->binning_end);
  80.  
  81.         ring = next_rb(ctx);
  82.  
  83.         ctx->binning_start = fd_ringmarker_new(ring);
  84.         ctx->binning_end = fd_ringmarker_new(ring);
  85.  
  86.         fd_ringbuffer_set_parent(ring, ctx->ring);
  87.         ctx->binning_ring = ring;
  88. }
  89.  
  90. /* emit accumulated render cmds, needed for example if render target has
  91.  * changed, or for flush()
  92.  */
  93. void
  94. fd_context_render(struct pipe_context *pctx)
  95. {
  96.         struct fd_context *ctx = fd_context(pctx);
  97.         struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
  98.         struct fd_resource *rsc, *rsc_tmp;
  99.         int i;
  100.  
  101.         DBG("needs_flush: %d", ctx->needs_flush);
  102.  
  103.         if (!ctx->needs_flush)
  104.                 return;
  105.  
  106.         fd_gmem_render_tiles(ctx);
  107.  
  108.         DBG("%p/%p/%p", ctx->ring->start, ctx->ring->cur, ctx->ring->end);
  109.  
  110.         /* if size in dwords is more than half the buffer size, then wait and
  111.          * wrap around:
  112.          */
  113.         if ((ctx->ring->cur - ctx->ring->start) > ctx->ring->size/8)
  114.                 fd_context_next_rb(pctx);
  115.  
  116.         ctx->needs_flush = false;
  117.         ctx->cleared = ctx->partial_cleared = ctx->restore = ctx->resolve = 0;
  118.         ctx->gmem_reason = 0;
  119.         ctx->num_draws = 0;
  120.  
  121.         for (i = 0; i < pfb->nr_cbufs; i++)
  122.                 if (pfb->cbufs[i])
  123.                         fd_resource(pfb->cbufs[i]->texture)->dirty = false;
  124.         if (pfb->zsbuf) {
  125.                 rsc = fd_resource(pfb->zsbuf->texture);
  126.                 rsc->dirty = false;
  127.                 if (rsc->stencil)
  128.                         rsc->stencil->dirty = false;
  129.         }
  130.  
  131.         /* go through all the used resources and clear their reading flag */
  132.         LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list) {
  133.                 assert(rsc->reading);
  134.                 rsc->reading = false;
  135.                 list_delinit(&rsc->list);
  136.         }
  137.  
  138.         assert(LIST_IS_EMPTY(&ctx->used_resources));
  139. }
  140.  
  141. static void
  142. fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
  143.                 unsigned flags)
  144. {
  145.         fd_context_render(pctx);
  146.  
  147.         if (fence)
  148.                 *fence = fd_fence_create(pctx);
  149. }
  150.  
  151. void
  152. fd_context_destroy(struct pipe_context *pctx)
  153. {
  154.         struct fd_context *ctx = fd_context(pctx);
  155.         unsigned i;
  156.  
  157.         DBG("");
  158.  
  159.         fd_prog_fini(pctx);
  160.         fd_hw_query_fini(pctx);
  161.  
  162.         util_dynarray_fini(&ctx->draw_patches);
  163.  
  164.         if (ctx->blitter)
  165.                 util_blitter_destroy(ctx->blitter);
  166.  
  167.         if (ctx->primconvert)
  168.                 util_primconvert_destroy(ctx->primconvert);
  169.  
  170.         util_slab_destroy(&ctx->transfer_pool);
  171.  
  172.         fd_ringmarker_del(ctx->draw_start);
  173.         fd_ringmarker_del(ctx->draw_end);
  174.         fd_ringmarker_del(ctx->binning_start);
  175.         fd_ringmarker_del(ctx->binning_end);
  176.  
  177.         for (i = 0; i < ARRAY_SIZE(ctx->rings); i++)
  178.                 fd_ringbuffer_del(ctx->rings[i]);
  179.  
  180.         for (i = 0; i < ARRAY_SIZE(ctx->pipe); i++) {
  181.                 struct fd_vsc_pipe *pipe = &ctx->pipe[i];
  182.                 if (!pipe->bo)
  183.                         break;
  184.                 fd_bo_del(pipe->bo);
  185.         }
  186.  
  187.         fd_device_del(ctx->dev);
  188.  
  189.         FREE(ctx);
  190. }
  191.  
  192. struct pipe_context *
  193. fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
  194.                 const uint8_t *primtypes, void *priv)
  195. {
  196.         struct fd_screen *screen = fd_screen(pscreen);
  197.         struct pipe_context *pctx;
  198.         int i;
  199.  
  200.         ctx->screen = screen;
  201.  
  202.         ctx->primtypes = primtypes;
  203.         ctx->primtype_mask = 0;
  204.         for (i = 0; i < PIPE_PRIM_MAX; i++)
  205.                 if (primtypes[i])
  206.                         ctx->primtype_mask |= (1 << i);
  207.  
  208.         /* need some sane default in case state tracker doesn't
  209.          * set some state:
  210.          */
  211.         ctx->sample_mask = 0xffff;
  212.  
  213.         pctx = &ctx->base;
  214.         pctx->screen = pscreen;
  215.         pctx->priv = priv;
  216.         pctx->flush = fd_context_flush;
  217.  
  218.         for (i = 0; i < ARRAY_SIZE(ctx->rings); i++) {
  219.                 ctx->rings[i] = fd_ringbuffer_new(screen->pipe, 0x100000);
  220.                 if (!ctx->rings[i])
  221.                         goto fail;
  222.         }
  223.  
  224.         fd_context_next_rb(pctx);
  225.         fd_reset_wfi(ctx);
  226.  
  227.         util_dynarray_init(&ctx->draw_patches);
  228.  
  229.         util_slab_create(&ctx->transfer_pool, sizeof(struct fd_transfer),
  230.                         16, UTIL_SLAB_SINGLETHREADED);
  231.  
  232.         fd_draw_init(pctx);
  233.         fd_resource_context_init(pctx);
  234.         fd_query_context_init(pctx);
  235.         fd_texture_init(pctx);
  236.         fd_state_init(pctx);
  237.         fd_hw_query_init(pctx);
  238.  
  239.         ctx->blitter = util_blitter_create(pctx);
  240.         if (!ctx->blitter)
  241.                 goto fail;
  242.  
  243.         ctx->primconvert = util_primconvert_create(pctx, ctx->primtype_mask);
  244.         if (!ctx->primconvert)
  245.                 goto fail;
  246.  
  247.         return pctx;
  248.  
  249. fail:
  250.         pctx->destroy(pctx);
  251.         return NULL;
  252. }
  253.