Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2012-2014 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 "core/ilo_builder_3d.h"
  29.  
  30. #include "ilo_common.h"
  31. #include "ilo_blitter.h"
  32. #include "ilo_state.h"
  33. #include "ilo_render_gen.h"
  34.  
  35. #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
  36.  
  37. static void
  38. gen6_emit_draw_surface_rt(struct ilo_render *r,
  39.                           const struct ilo_state_vector *vec,
  40.                           struct ilo_render_draw_session *session)
  41. {
  42.    const struct ilo_shader_state *fs = vec->fs;
  43.    const struct ilo_fb_state *fb = &vec->fb;
  44.    uint32_t *surface_state;
  45.    int base, count, i;
  46.  
  47.    ILO_DEV_ASSERT(r->dev, 6, 8);
  48.  
  49.    if (!DIRTY(FS) && !DIRTY(FB))
  50.       return;
  51.    if (!fs)
  52.       return;
  53.  
  54.    session->binding_table_fs_changed = true;
  55.  
  56.    base = ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_SURFACE_RT_BASE);
  57.    count = ilo_shader_get_kernel_param(fs, ILO_KERNEL_FS_SURFACE_RT_COUNT);
  58.  
  59.    /* SURFACE_STATEs for render targets */
  60.    surface_state = &r->state.wm.SURFACE_STATE[base];
  61.    for (i = 0; i < count; i++) {
  62.       if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
  63.          const struct ilo_surface_cso *surface =
  64.             (const struct ilo_surface_cso *) fb->state.cbufs[i];
  65.  
  66.          assert(surface->is_rt);
  67.          surface_state[i] =
  68.             gen6_SURFACE_STATE(r->builder, &surface->u.rt, true);
  69.       } else {
  70.          surface_state[i] =
  71.             gen6_SURFACE_STATE(r->builder, &fb->null_rt, true);
  72.       }
  73.    }
  74. }
  75.  
  76. static void
  77. gen6_emit_draw_surface_so(struct ilo_render *r,
  78.                           const struct ilo_state_vector *vec,
  79.                           struct ilo_render_draw_session *session)
  80. {
  81.    const struct ilo_shader_state *vs = vec->vs;
  82.    const struct ilo_shader_state *gs = vec->gs;
  83.    const struct ilo_so_state *so = &vec->so;
  84.    const struct pipe_stream_output_info *so_info;
  85.    uint32_t *surface_state;
  86.    int base, count, i;
  87.  
  88.    ILO_DEV_ASSERT(r->dev, 6, 6);
  89.  
  90.    if (!DIRTY(VS) && !DIRTY(GS) && !DIRTY(SO))
  91.       return;
  92.  
  93.    if (gs) {
  94.       so_info = ilo_shader_get_kernel_so_info(gs);
  95.       base = ilo_shader_get_kernel_param(gs,
  96.             ILO_KERNEL_GS_GEN6_SURFACE_SO_BASE);
  97.       count = ilo_shader_get_kernel_param(gs,
  98.             ILO_KERNEL_GS_GEN6_SURFACE_SO_COUNT);
  99.    } else if (vs) {
  100.       so_info = ilo_shader_get_kernel_so_info(vs);
  101.       base = 0;
  102.       count = ilo_shader_get_kernel_param(vs,
  103.             ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
  104.    } else {
  105.       return;
  106.    }
  107.  
  108.    session->binding_table_gs_changed = true;
  109.  
  110.    /* SURFACE_STATEs for stream output targets */
  111.    surface_state = &r->state.gs.SURFACE_STATE[base];
  112.    for (i = 0; i < count; i++) {
  113.       if (so_info && i < so_info->num_outputs &&
  114.           so_info->output[i].output_buffer < so->count &&
  115.           so->states[so_info->output[i].output_buffer]) {
  116.          const struct pipe_stream_output_target *so_target =
  117.             so->states[so_info->output[i].output_buffer];
  118.  
  119.          surface_state[i] = gen6_so_SURFACE_STATE(r->builder,
  120.                so_target, so_info, i);
  121.       } else {
  122.          surface_state[i] = 0;
  123.       }
  124.    }
  125. }
  126.  
  127. static void
  128. gen6_emit_draw_surface_view(struct ilo_render *r,
  129.                             const struct ilo_state_vector *vec,
  130.                             int shader_type,
  131.                             struct ilo_render_draw_session *session)
  132. {
  133.    const struct ilo_view_state *view = &vec->view[shader_type];
  134.    const struct ilo_shader_state *sh;
  135.    uint32_t *surface_state;
  136.    int base, count, i;
  137.  
  138.    ILO_DEV_ASSERT(r->dev, 6, 8);
  139.  
  140.    switch (shader_type) {
  141.    case PIPE_SHADER_VERTEX:
  142.       if (!DIRTY(VS) && !DIRTY(VIEW_VS))
  143.          return;
  144.       if (!vec->vs)
  145.          return;
  146.  
  147.       sh = vec->vs;
  148.       surface_state = r->state.vs.SURFACE_STATE;
  149.       session->binding_table_vs_changed = true;
  150.       break;
  151.    case PIPE_SHADER_FRAGMENT:
  152.       if (!DIRTY(FS) && !DIRTY(VIEW_FS))
  153.          return;
  154.       if (!vec->fs)
  155.          return;
  156.  
  157.       sh = vec->fs;
  158.       surface_state = r->state.wm.SURFACE_STATE;
  159.       session->binding_table_fs_changed = true;
  160.       break;
  161.    default:
  162.       return;
  163.       break;
  164.    }
  165.  
  166.    base = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_TEX_BASE);
  167.    count = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_TEX_COUNT);
  168.  
  169.    /* SURFACE_STATEs for sampler views */
  170.    surface_state += base;
  171.    for (i = 0; i < count; i++) {
  172.       if (i < view->count && view->states[i]) {
  173.          const struct ilo_view_cso *cso =
  174.             (const struct ilo_view_cso *) view->states[i];
  175.  
  176.          surface_state[i] =
  177.             gen6_SURFACE_STATE(r->builder, &cso->surface, false);
  178.       } else {
  179.          surface_state[i] = 0;
  180.       }
  181.    }
  182. }
  183.  
  184. static void
  185. gen6_emit_draw_surface_const(struct ilo_render *r,
  186.                              const struct ilo_state_vector *vec,
  187.                              int shader_type,
  188.                              struct ilo_render_draw_session *session)
  189. {
  190.    const struct ilo_cbuf_state *cbuf = &vec->cbuf[shader_type];
  191.    const struct ilo_shader_state *sh;
  192.    uint32_t *surface_state;
  193.    int base, count, i;
  194.  
  195.    ILO_DEV_ASSERT(r->dev, 6, 8);
  196.  
  197.    switch (shader_type) {
  198.    case PIPE_SHADER_VERTEX:
  199.       if (!DIRTY(VS) && !DIRTY(CBUF))
  200.          return;
  201.       if (!vec->vs)
  202.          return;
  203.  
  204.       sh = vec->vs;
  205.       surface_state = r->state.vs.SURFACE_STATE;
  206.       session->binding_table_vs_changed = true;
  207.       break;
  208.    case PIPE_SHADER_FRAGMENT:
  209.       if (!DIRTY(FS) && !DIRTY(CBUF))
  210.          return;
  211.       if (!vec->fs)
  212.          return;
  213.  
  214.       sh = vec->fs;
  215.       surface_state = r->state.wm.SURFACE_STATE;
  216.       session->binding_table_fs_changed = true;
  217.       break;
  218.    default:
  219.       return;
  220.       break;
  221.    }
  222.  
  223.    base = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_CONST_BASE);
  224.    count = ilo_shader_get_kernel_param(sh, ILO_KERNEL_SURFACE_CONST_COUNT);
  225.  
  226.    /* SURFACE_STATEs for constant buffers */
  227.    surface_state += base;
  228.    for (i = 0; i < count; i++) {
  229.       const struct ilo_cbuf_cso *cso = &cbuf->cso[i];
  230.  
  231.       if (cso->resource) {
  232.          surface_state[i] = gen6_SURFACE_STATE(r->builder,
  233.                &cso->surface, false);
  234.       } else {
  235.          surface_state[i] = 0;
  236.       }
  237.    }
  238. }
  239.  
  240. static void
  241. gen6_emit_draw_surface_binding_tables(struct ilo_render *r,
  242.                                       const struct ilo_state_vector *vec,
  243.                                       int shader_type,
  244.                                       struct ilo_render_draw_session *session)
  245. {
  246.    int count;
  247.  
  248.    ILO_DEV_ASSERT(r->dev, 6, 8);
  249.  
  250.    /* BINDING_TABLE_STATE */
  251.    switch (shader_type) {
  252.    case PIPE_SHADER_VERTEX:
  253.       if (!session->binding_table_vs_changed)
  254.          return;
  255.       if (!vec->vs)
  256.          return;
  257.  
  258.       count = ilo_shader_get_kernel_param(vec->vs,
  259.             ILO_KERNEL_SURFACE_TOTAL_COUNT);
  260.  
  261.       r->state.vs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
  262.             r->state.vs.SURFACE_STATE, count);
  263.       break;
  264.    case PIPE_SHADER_GEOMETRY:
  265.       if (!session->binding_table_gs_changed)
  266.          return;
  267.       if (vec->gs) {
  268.          count = ilo_shader_get_kernel_param(vec->gs,
  269.                ILO_KERNEL_SURFACE_TOTAL_COUNT);
  270.       } else if (ilo_dev_gen(r->dev) == ILO_GEN(6) && vec->vs) {
  271.          count = ilo_shader_get_kernel_param(vec->vs,
  272.                ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
  273.       } else {
  274.          return;
  275.       }
  276.  
  277.       r->state.gs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
  278.             r->state.gs.SURFACE_STATE, count);
  279.       break;
  280.    case PIPE_SHADER_FRAGMENT:
  281.       if (!session->binding_table_fs_changed)
  282.          return;
  283.       if (!vec->fs)
  284.          return;
  285.  
  286.       count = ilo_shader_get_kernel_param(vec->fs,
  287.             ILO_KERNEL_SURFACE_TOTAL_COUNT);
  288.  
  289.       r->state.wm.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
  290.             r->state.wm.SURFACE_STATE, count);
  291.       break;
  292.    default:
  293.       break;
  294.    }
  295. }
  296.  
  297. #undef DIRTY
  298.  
  299. int
  300. ilo_render_get_draw_surface_states_len(const struct ilo_render *render,
  301.                                        const struct ilo_state_vector *vec)
  302. {
  303.    int sh_type, len;
  304.  
  305.    ILO_DEV_ASSERT(render->dev, 6, 8);
  306.  
  307.    len = 0;
  308.  
  309.    for (sh_type = 0; sh_type < PIPE_SHADER_TYPES; sh_type++) {
  310.       const int alignment =
  311.          (ilo_dev_gen(render->dev) >= ILO_GEN(8) ? 64 : 32) / 4;
  312.       int num_surfaces = 0;
  313.  
  314.       switch (sh_type) {
  315.       case PIPE_SHADER_VERTEX:
  316.          if (vec->vs) {
  317.             num_surfaces = ilo_shader_get_kernel_param(vec->vs,
  318.                   ILO_KERNEL_SURFACE_TOTAL_COUNT);
  319.  
  320.             if (ilo_dev_gen(render->dev) == ILO_GEN(6)) {
  321.                num_surfaces += ilo_shader_get_kernel_param(vec->vs,
  322.                      ILO_KERNEL_VS_GEN6_SO_SURFACE_COUNT);
  323.             }
  324.          }
  325.          break;
  326.       case PIPE_SHADER_GEOMETRY:
  327.          if (vec->gs) {
  328.             num_surfaces = ilo_shader_get_kernel_param(vec->gs,
  329.                   ILO_KERNEL_SURFACE_TOTAL_COUNT);
  330.          }
  331.          break;
  332.       case PIPE_SHADER_FRAGMENT:
  333.          if (vec->fs) {
  334.             num_surfaces = ilo_shader_get_kernel_param(vec->fs,
  335.                   ILO_KERNEL_SURFACE_TOTAL_COUNT);
  336.          }
  337.          break;
  338.       default:
  339.          break;
  340.       }
  341.  
  342.       /* BINDING_TABLE_STATE and SURFACE_STATEs */
  343.       if (num_surfaces) {
  344.          len += align(num_surfaces, alignment) +
  345.             align(GEN6_SURFACE_STATE__SIZE, alignment) * num_surfaces;
  346.       }
  347.    }
  348.  
  349.    return len;
  350. }
  351.  
  352. void
  353. ilo_render_emit_draw_surface_states(struct ilo_render *render,
  354.                                     const struct ilo_state_vector *vec,
  355.                                     struct ilo_render_draw_session *session)
  356. {
  357.    const unsigned surface_used = ilo_builder_surface_used(render->builder);
  358.    int shader_type;
  359.  
  360.    ILO_DEV_ASSERT(render->dev, 6, 8);
  361.  
  362.    /*
  363.     * upload all SURAFCE_STATEs together so that we know there are minimal
  364.     * paddings
  365.     */
  366.  
  367.    gen6_emit_draw_surface_rt(render, vec, session);
  368.  
  369.    if (ilo_dev_gen(render->dev) == ILO_GEN(6))
  370.       gen6_emit_draw_surface_so(render, vec, session);
  371.  
  372.    for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
  373.       gen6_emit_draw_surface_view(render, vec, shader_type, session);
  374.       gen6_emit_draw_surface_const(render, vec, shader_type, session);
  375.    }
  376.  
  377.    /* this must be called after all SURFACE_STATEs have been uploaded */
  378.    for (shader_type = 0; shader_type < PIPE_SHADER_TYPES; shader_type++) {
  379.       gen6_emit_draw_surface_binding_tables(render, vec,
  380.             shader_type, session);
  381.    }
  382.  
  383.    assert(ilo_builder_surface_used(render->builder) <= surface_used +
  384.          ilo_render_get_draw_surface_states_len(render, vec));
  385. }
  386.  
  387. static void
  388. gen6_emit_launch_grid_surface_view(struct ilo_render *r,
  389.                                    const struct ilo_state_vector *vec,
  390.                                    struct ilo_render_launch_grid_session *session)
  391. {
  392.    const struct ilo_shader_state *cs = vec->cs;
  393.    const struct ilo_view_state *view = &vec->view[PIPE_SHADER_COMPUTE];
  394.    uint32_t *surface_state = r->state.cs.SURFACE_STATE;
  395.    int base, count, i;
  396.  
  397.    ILO_DEV_ASSERT(r->dev, 7, 7.5);
  398.  
  399.    base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_BASE);
  400.    count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TEX_COUNT);
  401.  
  402.    /* SURFACE_STATEs for sampler views */
  403.    surface_state += base;
  404.    for (i = 0; i < count; i++) {
  405.       if (i < view->count && view->states[i]) {
  406.          const struct ilo_view_cso *cso =
  407.             (const struct ilo_view_cso *) view->states[i];
  408.  
  409.          surface_state[i] =
  410.             gen6_SURFACE_STATE(r->builder, &cso->surface, false);
  411.       } else {
  412.          surface_state[i] = 0;
  413.       }
  414.    }
  415. }
  416.  
  417. static void
  418. gen6_emit_launch_grid_surface_const(struct ilo_render *r,
  419.                                     const struct ilo_state_vector *vec,
  420.                                     struct ilo_render_launch_grid_session *session)
  421. {
  422.    const struct ilo_shader_state *cs = vec->cs;
  423.    uint32_t *surface_state = r->state.cs.SURFACE_STATE;
  424.    struct ilo_view_surface view;
  425.    int base, count;
  426.  
  427.    ILO_DEV_ASSERT(r->dev, 7, 7.5);
  428.  
  429.    base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_BASE);
  430.    count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_CONST_COUNT);
  431.  
  432.    if (!count)
  433.       return;
  434.  
  435.    ilo_gpe_init_view_surface_for_buffer(r->dev,
  436.          ilo_buffer(session->input->buffer),
  437.          session->input->buffer_offset,
  438.          session->input->buffer_size,
  439.          1, PIPE_FORMAT_NONE,
  440.          false, false, &view);
  441.  
  442.    assert(count == 1 && session->input->buffer);
  443.    surface_state[base] = gen6_SURFACE_STATE(r->builder, &view, false);
  444. }
  445.  
  446. static void
  447. gen6_emit_launch_grid_surface_cs_resource(struct ilo_render *r,
  448.                                           const struct ilo_state_vector *vec,
  449.                                           struct ilo_render_launch_grid_session *session)
  450. {
  451.    ILO_DEV_ASSERT(r->dev, 7, 7.5);
  452.  
  453.    /* TODO */
  454.    assert(!vec->cs_resource.count);
  455. }
  456.  
  457. static void
  458. gen6_emit_launch_grid_surface_global(struct ilo_render *r,
  459.                                           const struct ilo_state_vector *vec,
  460.                                           struct ilo_render_launch_grid_session *session)
  461. {
  462.    const struct ilo_shader_state *cs = vec->cs;
  463.    const struct ilo_global_binding_cso *bindings =
  464.       util_dynarray_begin(&vec->global_binding.bindings);
  465.    uint32_t *surface_state = r->state.cs.SURFACE_STATE;
  466.    int base, count, i;
  467.  
  468.    ILO_DEV_ASSERT(r->dev, 7, 7.5);
  469.  
  470.    base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
  471.    count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
  472.  
  473.    if (!count)
  474.       return;
  475.  
  476.    if (base + count > Elements(r->state.cs.SURFACE_STATE)) {
  477.       ilo_warn("too many global bindings\n");
  478.       count = Elements(r->state.cs.SURFACE_STATE) - base;
  479.    }
  480.  
  481.    /* SURFACE_STATEs for global bindings */
  482.    surface_state += base;
  483.    for (i = 0; i < count; i++) {
  484.       if (i < vec->global_binding.count && bindings[i].resource) {
  485.          const struct ilo_buffer *buf = ilo_buffer(bindings[i].resource);
  486.          struct ilo_view_surface view;
  487.  
  488.          assert(bindings[i].resource->target == PIPE_BUFFER);
  489.  
  490.          ilo_gpe_init_view_surface_for_buffer(r->dev, buf, 0, buf->bo_size,
  491.                1, PIPE_FORMAT_NONE, true, true, &view);
  492.          surface_state[i] =
  493.             gen6_SURFACE_STATE(r->builder, &view, true);
  494.       } else {
  495.          surface_state[i] = 0;
  496.       }
  497.    }
  498. }
  499.  
  500. static void
  501. gen6_emit_launch_grid_surface_binding_table(struct ilo_render *r,
  502.                                             const struct ilo_state_vector *vec,
  503.                                             struct ilo_render_launch_grid_session *session)
  504. {
  505.    const struct ilo_shader_state *cs = vec->cs;
  506.    int count;
  507.  
  508.    ILO_DEV_ASSERT(r->dev, 7, 7.5);
  509.  
  510.    count = ilo_shader_get_kernel_param(cs, ILO_KERNEL_SURFACE_TOTAL_COUNT);
  511.    if (count) {
  512.       r->state.cs.BINDING_TABLE_STATE = gen6_BINDING_TABLE_STATE(r->builder,
  513.             r->state.cs.SURFACE_STATE, count);
  514.    }
  515. }
  516.  
  517. int
  518. ilo_render_get_launch_grid_surface_states_len(const struct ilo_render *render,
  519.                                               const struct ilo_state_vector *vec)
  520. {
  521.    const int alignment = 32 / 4;
  522.    int num_surfaces;
  523.    int len = 0;
  524.  
  525.    ILO_DEV_ASSERT(render->dev, 7, 7.5);
  526.  
  527.    num_surfaces = ilo_shader_get_kernel_param(vec->cs,
  528.          ILO_KERNEL_SURFACE_TOTAL_COUNT);
  529.  
  530.    /* BINDING_TABLE_STATE and SURFACE_STATEs */
  531.    if (num_surfaces) {
  532.       len += align(num_surfaces, alignment) +
  533.          align(GEN6_SURFACE_STATE__SIZE, alignment) * num_surfaces;
  534.    }
  535.  
  536.    return len;
  537. }
  538.  
  539. void
  540. ilo_render_emit_launch_grid_surface_states(struct ilo_render *render,
  541.                                            const struct ilo_state_vector *vec,
  542.                                            struct ilo_render_launch_grid_session *session)
  543. {
  544.    const unsigned surface_used = ilo_builder_surface_used(render->builder);
  545.  
  546.    ILO_DEV_ASSERT(render->dev, 7, 7.5);
  547.  
  548.    /* idrt depends on the binding table */
  549.    assert(!session->idrt_size);
  550.  
  551.    gen6_emit_launch_grid_surface_view(render, vec, session);
  552.    gen6_emit_launch_grid_surface_const(render, vec, session);
  553.    gen6_emit_launch_grid_surface_cs_resource(render, vec, session);
  554.    gen6_emit_launch_grid_surface_global(render, vec, session);
  555.    gen6_emit_launch_grid_surface_binding_table(render, vec, session);
  556.  
  557.    assert(ilo_builder_surface_used(render->builder) <= surface_used +
  558.          ilo_render_get_launch_grid_surface_states_len(render, vec));
  559. }
  560.