Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 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_prim.h"
  29. #include "intel_winsys.h"
  30.  
  31. #include "ilo_context.h"
  32. #include "ilo_cp.h"
  33. #include "ilo_state.h"
  34. #include "ilo_3d_pipeline_gen6.h"
  35. #include "ilo_3d_pipeline_gen7.h"
  36. #include "ilo_3d_pipeline.h"
  37.  
  38. /* in U0.4 */
  39. struct sample_position {
  40.    uint8_t x, y;
  41. };
  42.  
  43. /* \see gen6_get_sample_position() */
  44. static const struct sample_position sample_position_1x[1] = {
  45.    {  8,  8 },
  46. };
  47.  
  48. static const struct sample_position sample_position_4x[4] = {
  49.    {  6,  2 }, /* distance from the center is sqrt(40) */
  50.    { 14,  6 }, /* distance from the center is sqrt(40) */
  51.    {  2, 10 }, /* distance from the center is sqrt(40) */
  52.    { 10, 14 }, /* distance from the center is sqrt(40) */
  53. };
  54.  
  55. static const struct sample_position sample_position_8x[8] = {
  56.    {  7,  9 }, /* distance from the center is sqrt(2) */
  57.    {  9, 13 }, /* distance from the center is sqrt(26) */
  58.    { 11,  3 }, /* distance from the center is sqrt(34) */
  59.    { 13, 11 }, /* distance from the center is sqrt(34) */
  60.    {  1,  7 }, /* distance from the center is sqrt(50) */
  61.    {  5,  1 }, /* distance from the center is sqrt(58) */
  62.    { 15,  5 }, /* distance from the center is sqrt(58) */
  63.    {  3, 15 }, /* distance from the center is sqrt(74) */
  64. };
  65.  
  66. struct ilo_3d_pipeline *
  67. ilo_3d_pipeline_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
  68. {
  69.    struct ilo_3d_pipeline *p;
  70.    int i;
  71.  
  72.    p = CALLOC_STRUCT(ilo_3d_pipeline);
  73.    if (!p)
  74.       return NULL;
  75.  
  76.    p->cp = cp;
  77.    p->dev = dev;
  78.  
  79.    switch (p->dev->gen) {
  80.    case ILO_GEN(6):
  81.       ilo_3d_pipeline_init_gen6(p);
  82.       break;
  83.    case ILO_GEN(7):
  84.       ilo_3d_pipeline_init_gen7(p);
  85.       break;
  86.    default:
  87.       assert(!"unsupported GEN");
  88.       FREE(p);
  89.       return NULL;
  90.       break;
  91.    }
  92.  
  93.    p->invalidate_flags = ILO_3D_PIPELINE_INVALIDATE_ALL;
  94.  
  95.    p->workaround_bo = intel_winsys_alloc_buffer(p->cp->winsys,
  96.          "PIPE_CONTROL workaround", 4096, 0);
  97.    if (!p->workaround_bo) {
  98.       ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n");
  99.       FREE(p);
  100.       return NULL;
  101.    }
  102.  
  103.    p->packed_sample_position_1x =
  104.       sample_position_1x[0].x << 4 |
  105.       sample_position_1x[0].y;
  106.  
  107.    /* pack into dwords */
  108.    for (i = 0; i < 4; i++) {
  109.       p->packed_sample_position_4x |=
  110.          sample_position_4x[i].x << (8 * i + 4) |
  111.          sample_position_4x[i].y << (8 * i);
  112.  
  113.       p->packed_sample_position_8x[0] |=
  114.          sample_position_8x[i].x << (8 * i + 4) |
  115.          sample_position_8x[i].y << (8 * i);
  116.  
  117.       p->packed_sample_position_8x[1] |=
  118.          sample_position_8x[4 + i].x << (8 * i + 4) |
  119.          sample_position_8x[4 + i].y << (8 * i);
  120.    }
  121.  
  122.    return p;
  123. }
  124.  
  125. void
  126. ilo_3d_pipeline_destroy(struct ilo_3d_pipeline *p)
  127. {
  128.    if (p->workaround_bo)
  129.       intel_bo_unreference(p->workaround_bo);
  130.  
  131.    FREE(p);
  132. }
  133.  
  134. static void
  135. handle_invalid_batch_bo(struct ilo_3d_pipeline *p, bool unset)
  136. {
  137.    if (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_BATCH_BO) {
  138.       if (p->dev->gen == ILO_GEN(6))
  139.          p->state.has_gen6_wa_pipe_control = false;
  140.  
  141.       if (unset)
  142.          p->invalidate_flags &= ~ILO_3D_PIPELINE_INVALIDATE_BATCH_BO;
  143.    }
  144. }
  145.  
  146. /**
  147.  * Emit context states and 3DPRIMITIVE.
  148.  */
  149. bool
  150. ilo_3d_pipeline_emit_draw(struct ilo_3d_pipeline *p,
  151.                           const struct ilo_context *ilo,
  152.                           int *prim_generated, int *prim_emitted)
  153. {
  154.    bool success;
  155.  
  156.    if (ilo->dirty & ILO_DIRTY_SO &&
  157.        ilo->so.enabled && !ilo->so.append_bitmask) {
  158.       /*
  159.        * We keep track of the SVBI in the driver, so that we can restore it
  160.        * when the HW context is invalidated (by another process).  The value
  161.        * needs to be reset when stream output is enabled and the targets are
  162.        * changed.
  163.        */
  164.       p->state.so_num_vertices = 0;
  165.  
  166.       /* on GEN7+, we need SOL_RESET to reset the SO write offsets */
  167.       if (p->dev->gen >= ILO_GEN(7))
  168.          ilo_cp_set_one_off_flags(p->cp, INTEL_EXEC_GEN7_SOL_RESET);
  169.    }
  170.  
  171.  
  172.    while (true) {
  173.       struct ilo_cp_jmp_buf jmp;
  174.       int err;
  175.  
  176.       /* we will rewind if aperture check below fails */
  177.       ilo_cp_setjmp(p->cp, &jmp);
  178.  
  179.       handle_invalid_batch_bo(p, false);
  180.  
  181.       /* draw! */
  182.       ilo_cp_assert_no_implicit_flush(p->cp, true);
  183.       p->emit_draw(p, ilo);
  184.       ilo_cp_assert_no_implicit_flush(p->cp, false);
  185.  
  186.       err = intel_winsys_check_aperture_space(ilo->winsys, &p->cp->bo, 1);
  187.       if (!err) {
  188.          success = true;
  189.          break;
  190.       }
  191.  
  192.       /* rewind */
  193.       ilo_cp_longjmp(p->cp, &jmp);
  194.  
  195.       if (ilo_cp_empty(p->cp)) {
  196.          success = false;
  197.          break;
  198.       }
  199.       else {
  200.          /* flush and try again */
  201.          ilo_cp_flush(p->cp);
  202.       }
  203.    }
  204.  
  205.    if (success) {
  206.       const int num_verts =
  207.          u_vertices_per_prim(u_reduced_prim(ilo->draw->mode));
  208.       const int max_emit =
  209.          (p->state.so_max_vertices - p->state.so_num_vertices) / num_verts;
  210.       const int generated =
  211.          u_reduced_prims_for_vertices(ilo->draw->mode, ilo->draw->count);
  212.       const int emitted = MIN2(generated, max_emit);
  213.  
  214.       p->state.so_num_vertices += emitted * num_verts;
  215.  
  216.       if (prim_generated)
  217.          *prim_generated = generated;
  218.  
  219.       if (prim_emitted)
  220.          *prim_emitted = emitted;
  221.    }
  222.  
  223.    p->invalidate_flags = 0x0;
  224.  
  225.    return success;
  226. }
  227.  
  228. /**
  229.  * Emit PIPE_CONTROL to flush all caches.
  230.  */
  231. void
  232. ilo_3d_pipeline_emit_flush(struct ilo_3d_pipeline *p)
  233. {
  234.    handle_invalid_batch_bo(p, true);
  235.    p->emit_flush(p);
  236. }
  237.  
  238. /**
  239.  * Emit PIPE_CONTROL with PIPE_CONTROL_WRITE_TIMESTAMP post-sync op.
  240.  */
  241. void
  242. ilo_3d_pipeline_emit_write_timestamp(struct ilo_3d_pipeline *p,
  243.                                      struct intel_bo *bo, int index)
  244. {
  245.    handle_invalid_batch_bo(p, true);
  246.    p->emit_write_timestamp(p, bo, index);
  247. }
  248.  
  249. /**
  250.  * Emit PIPE_CONTROL with PIPE_CONTROL_WRITE_DEPTH_COUNT post-sync op.
  251.  */
  252. void
  253. ilo_3d_pipeline_emit_write_depth_count(struct ilo_3d_pipeline *p,
  254.                                        struct intel_bo *bo, int index)
  255. {
  256.    handle_invalid_batch_bo(p, true);
  257.    p->emit_write_depth_count(p, bo, index);
  258. }
  259.  
  260. void
  261. ilo_3d_pipeline_get_sample_position(struct ilo_3d_pipeline *p,
  262.                                     unsigned sample_count,
  263.                                     unsigned sample_index,
  264.                                     float *x, float *y)
  265. {
  266.    const struct sample_position *pos;
  267.  
  268.    switch (sample_count) {
  269.    case 1:
  270.       assert(sample_index < Elements(sample_position_1x));
  271.       pos = sample_position_1x;
  272.       break;
  273.    case 4:
  274.       assert(sample_index < Elements(sample_position_4x));
  275.       pos = sample_position_4x;
  276.       break;
  277.    case 8:
  278.       assert(sample_index < Elements(sample_position_8x));
  279.       pos = sample_position_8x;
  280.       break;
  281.    default:
  282.       assert(!"unknown sample count");
  283.       *x = 0.5f;
  284.       *y = 0.5f;
  285.       return;
  286.       break;
  287.    }
  288.  
  289.    *x = (float) pos[sample_index].x / 16.0f;
  290.    *y = (float) pos[sample_index].y / 16.0f;
  291. }
  292.